Skip to content

Identity integration and external access policy

This document defines how Astrocyte composes with authentication (AuthN) and external authorization (AuthZ) systems without becoming an identity provider or coupling to any single vendor. For the default in-framework model (opaque principals + YAML grants), see access-control.md.


GoalApproach
AdoptionTeams using OIDC, SAML, API keys, workload identity, or commercial IdPs should integrate with patterns and optional thin adapters, not forks of Astrocyte.
StabilityCore ships interfaces + default behavior; vendor-specific code lives in astrocyte-access-policy-* or astrocyte-identity-* optional packages.
Clear boundariesAstrocyte never replaces your IdP. It enforces memory permissions at the framework boundary and emits audit events for allow/deny.
Optional central policyEnterprises using OPA, Casbin, Cedar, SpiceDB, Cerbos, Permit.io, etc. can plug a policy decision behind a small SPI while keeping bank semantics and auditing in Astrocyte.

  • Run an OAuth2 / OIDC server, issue sessions, or store passwords.
  • Validate JWTs or API keys inside the memory engine by default (that stays in middleware or sidecar).
  • Embed Keycloak, Casdoor, Auth0, Okta, or commercial PDP SDKs in the astrocyte core package.

Casdoor (open-source IAM / OIDC-SAML-ldap) and similar IdPs are deployed by you; Astrocyte only receives the resulting principal after your middleware validates tokens or sessions.

Those systems remain infrastructure; Astrocyte consumes their outputs (identity attributes, allow/deny decisions) through documented extension points.


3. Authentication: from credential to principal

Section titled “3. Authentication: from credential to principal”

Astrocyte continues to accept an opaque principal string (see access-control.md §1.1). Authentication is the step that runs before AstrocyteContext is built:

HTTP request / MCP session / workload attestation
→ YOUR AuthN layer (middleware, sidecar, agent runtime)
→ verified identity + claims
→ map to principal string (convention: agent:, user:, service:, …)
→ AstrocyteContext(principal=...)
→ brain.retain / recall / …

Integration options (non-exclusive):

  1. Application code - After your web framework’s auth dependency runs, set principal from sub, email, or an internal user ID.
  2. Optional helper packages - e.g. astrocyte-identity-oidc (hypothetical) that maps standard JWT claims to a stable principal format; still your tokens, your issuer validation. If you use Casdoor as IdP, the same pattern applies: validate OIDC access tokens from Casdoor (or rely on Casdoor’s application integration), then map sub / username / organization claims to user:{id} or agent:{id} principals.
  3. MCP / agent hosts - Map the host’s authenticated agent or user to a principal (see mcp-server.md); extend with 21 patterns when MCP exposes richer client identity.

The core trusts the principal the same way it does today; integration work is wiring, not a second memory API.


4. Authorization: config grants vs. external policy (PDP)

Section titled “4. Authorization: config grants vs. external policy (PDP)”

4.1 Default: declarative grants in Astrocyte

Section titled “4.1 Default: declarative grants in Astrocyte”

The default authorizer evaluates per-bank grants from config or programmatic APIs (grant_access, etc.). No external call. This remains the right default for most open-source users.

For organizations that centralize authorization in a PDP (Policy Decision Point), Astrocyte defines an optional interface:

  • Input: principal, bank_id, permission (read | write | forget | admin), and optional context (tenant id, request metadata, resource tags - implementation-defined).
  • Output: allow or deny (and optional reason string for audit).
  • Placement: Called at the same enforcement point as today’s access check - after rate limits / sanitization, before pipeline or engine (see access-control.md §3.1).

Composition rule: The SPI can replace or chain with config grants:

ModeBehavior
external_onlyOnly the external PDP decides (config grants ignored for enforcement, or used as cache hints - product choice).
config_then_externalDeny if config denies; if config allows, optionally ask PDP for ABAC attributes.
external_then_configPDP for coarse tenant rules; config grants for fine-grained bank ACLs.

Exact chaining modes are configuration on Astrocyte; the SPI remains a single check(...) surface.

StyleExamplesAccessPolicyProvider adapter
Remote / service PDPOPA (REST), Cerbos (gRPC/HTTP), Permit APINetwork client in astrocyte-access-policy-opa, etc.
In-process enforcerCasbin (RBAC/ABAC/ReBAC via model + policy files)Thin wrapper: check() calls enforcer.enforce(subject, object, action) with Astrocyte’ principal, bank_id, and permission mapped to Casbin tuples - package e.g. astrocyte-access-policy-casbin. No HTTP hop; policies ship with your app or load from your store.

Casbin is a common choice when teams want embedded authorization with explicit CSV/model files; OPA/Cerbos when policy is centralized and shared across services.

4.4 Why not put OPA/Cerbos/Casbin inside core?

Section titled “4.4 Why not put OPA/Cerbos/Casbin inside core?”
  • Different enterprises standardize on different PDPs or enforcers.
  • Network latency, availability, and versioning belong at the integration layer (or in your Casbin model lifecycle).
  • Keeping adapters in astrocyte-access-policy-{name} packages preserves a slim core and faster security patches per integration.

ArtifactRole
astrocyteAccessPolicyProvider protocol (optional), default config-based authorizer, audit hooks.
astrocyte-access-policy-opa (example)Calls OPA REST API with Rego bundles maintained by the user.
astrocyte-access-policy-cerbos (example)Cerbos gRPC/HTTP SDK adapter.
astrocyte-access-policy-casbin (example)Wraps a Casbin Enforcer for in-process RBAC/ABAC aligned to bank permissions.
astrocyte-identity-fastapi (example)Optional helpers: FastAPI dependency that validates JWT and sets AstrocyteContext.
astrocyte-identity-casdoor (example)Optional helpers for OIDC flows where Casdoor is the issuer (claim → principal mapping).

Entry point group (illustrative):

[project.entry-points."astrocyte.access_policies"]
opa = "astrocyte_access_policy_opa:OPAAccessPolicyProvider"
casbin = "astrocyte_access_policy_casbin:CasbinAccessPolicyProvider"

Config sketch (illustrative):

access_control:
enabled: true
policy_provider: opa # optional; omit for config-only
policy_provider_config:
base_url: http://localhost:8181
policy_package: astrocyte.memory

External PDP decisions must still produce audit events compatible with access-control.md §6:

  • Include policy_provider name in structured fields.
  • Log deny with reason from PDP when available.
  • Never log secrets, raw tokens, or full claim payloads by default.

DocumentTopic
access-control.mdPrincipals, permissions, grants, enforcement order
architecture-framework.mdWhere identity/policy integration sits in the layer model
ecosystem-and-packaging.mdEntry points and optional package naming
mcp-server.mdMCP-scoped identity today; extend with §3 above
production-grade-http-service.mdReference HTTP service; AuthN/AuthZ checklist

This section names which folders own AuthZ wiring in astrocyte-py versus astrocyte-services-py. It is not a substitute for the full design in §3–§5 above.

8.1 In-framework grants (AccessGrant + set_access_grants)

Section titled “8.1 In-framework grants (AccessGrant + set_access_grants)”
ResponsibilityLocation
AccessGrant, Astrocyte.set_access_grants(), _check_access()astrocyte-py — core types and enforcement (astrocyte/types.py, astrocyte/_astrocyte.py).
Parsing grants from YAML (e.g. top-level access_grants, or consolidating banks.*.access from access-control.md §2.1 into a flat list)astrocyte-py — extend AstrocyteConfig / load_config / _dict_to_config in astrocyte/config.py so config loading produces a list[AccessGrant] (or a helper that builds it from config).
Calling set_access_grants() at process startupastrocyte-services-py/astrocyte-restastrocyte_rest/brain.py (build_astrocyte()): after Astrocyte(config) and set_pipeline(...), apply grants from the loaded config.
Trusted principal on each HTTP request (production)astrocyte-rest — FastAPI dependencies / middleware: map verified JWT, API key, mTLS identity to AstrocyteContext, not an unauthenticated client header alone.

Not here: astrocyte-pgvector — it implements VectorStore only; it does not participate in access grants.

ResponsibilityLocation
Protocol and enforcement hook (e.g. call PDP from the same place as grant checks)astrocyte-py — define AccessPolicyProvider, integrate with Astrocyte (e.g. alongside _check_access). As of this writing the SPI may be documented ahead of full implementation; align code with this doc when landing it.
Vendor-specific client (OPA REST, Cerbos SDK, Casbin Enforcer, etc.)Separate optional packages — e.g. astrocyte-access-policy-opa, astrocyte-access-policy-cerbos (see §5). Keeps astrocyte free of third-party PDP SDKs.
Instantiate adapter + attach to Astrocyteastrocyte-services-py/astrocyte-restbrain.py (or equivalent factory): resolve provider via config entry point / env, same pattern as vector_store in astrocyte_rest/wiring.py.

Not here: astrocyte-pgvector — unchanged; storage adapters are not AuthZ layers.

Approachastrocyte-pyastrocyte-restOptional astrocyte-access-policy-*
GrantsConfig model + load → AccessGrant list; set_access_grants APICall set_access_grants at startup; later, AuthN → principal
External PDPSPI + Astrocyte integrationWire provider at startupOPA / Cerbos / Casbin / … adapters

  • AuthNyour middleware or optional astrocyte-identity-* helpers → principal string.
  • AuthZdefault YAML grants, or optional AccessPolicyProvider + astrocyte-access-policy-* for OPA, Cerbos, Casbin, etc.
  • Astrocyte stays the memory barrier and audit anchor; IdPs and PDPs stay pluggable.
  • Repository placement for grants vs PDP vs storage: see §8 above.