Skip to content

Authentication setup

Step-by-step guide for configuring authentication on the Astrocyte standalone gateway (astrocyte-gateway-py). Covers all four auth modes, access grants, and integration with OIDC providers.


Set ASTROCYTE_AUTH_MODE to select how the gateway authenticates incoming requests:

ModeEnv var valueClient sendsMaps toProduction?
Devdev (default)X-Astrocyte-Principal headerprincipalNo
API keyapi_keyX-Api-Key + X-Astrocyte-PrincipalprincipalInternal only
JWT HS256jwt_hs256 or jwtAuthorization: Bearer <token>principal from sub claimYes (symmetric)
JWT OIDCjwt_oidcAuthorization: Bearer <token>principal, actor, tenant_id from claimsYes (enterprise SSO)

Every mode produces an AstrocyteContext that flows to all operations — retain, recall, reflect, forget — and drives access control when enabled.


Trusts the client-supplied principal header with no verification. Use only for local development and testing.

.env
ASTROCYTE_AUTH_MODE=dev

Client request:

Terminal window
curl -X POST http://localhost:8080/v1/retain \
-H "Content-Type: application/json" \
-H "X-Astrocyte-Principal: user:alice" \
-d '{"content": "Alice likes dark mode", "bank_id": "user-alice"}'

If the header is omitted, the request proceeds as anonymous (no principal, no access control).


Shared secret verified with constant-time HMAC comparison. The client sends both the key and a principal header.

.env
ASTROCYTE_AUTH_MODE=api_key
ASTROCYTE_API_KEY=sk-your-secret-key-here

Client request:

Terminal window
curl -X POST http://localhost:8080/v1/recall \
-H "Content-Type: application/json" \
-H "X-Api-Key: sk-your-secret-key-here" \
-H "X-Astrocyte-Principal: agent:support-bot" \
-d '{"query": "user preferences", "bank_id": "shared"}'

Errors:

StatusDetailCause
401Invalid or missing API keyX-Api-Key does not match ASTROCYTE_API_KEY
401X-Astrocyte-Principal requiredX-Astrocyte-Principal header missing or empty
500ASTROCYTE_API_KEY is not setEnv var not configured

When to use: Service-to-service calls where both sides share a secret. No key rotation mechanism — rotate by redeploying with a new value.


Symmetric-key JWT verification. The issuer and gateway share a secret. The sub claim becomes the principal.

.env
ASTROCYTE_AUTH_MODE=jwt_hs256
ASTROCYTE_JWT_SECRET=your-256-bit-secret
ASTROCYTE_JWT_AUDIENCE=astrocyte # optional but recommended
import jwt, time
token = jwt.encode(
{
"sub": "user:alice",
"aud": "astrocyte",
"iat": int(time.time()),
"exp": int(time.time()) + 3600,
},
"your-256-bit-secret",
algorithm="HS256",
)
print(token)
Terminal window
curl -X POST http://localhost:8080/v1/recall \
-H "Content-Type: application/json" \
-H "Authorization: Bearer eyJhbGci..." \
-d '{"query": "user preferences", "bank_id": "user-alice"}'
ClaimRequiredDescription
subYesPrincipal string (e.g. user:alice, agent:bot-1)
audIf ASTROCYTE_JWT_AUDIENCE is setMust match exactly
expRecommendedExpiry timestamp
iatRecommendedIssued-at timestamp

If ASTROCYTE_JWT_AUDIENCE is not set, the gateway logs a warning and skips audience validation.

Errors:

StatusDetailCause
401Bearer token requiredAuthorization header missing or not Bearer ...
401Invalid tokenSignature invalid, expired, or audience mismatch
401Token missing subsub claim absent or not a string
500ASTROCYTE_JWT_SECRET is not setEnv var not configured

Asymmetric JWT verification using your IdP’s JWKS endpoint. The gateway fetches public keys from the IdP and verifies RS256 signatures — no shared secret needed.

.env
ASTROCYTE_AUTH_MODE=jwt_oidc
ASTROCYTE_OIDC_JWKS_URL=https://auth.example.com/.well-known/jwks.json
ASTROCYTE_OIDC_ISSUER=https://auth.example.com
ASTROCYTE_OIDC_AUDIENCE=astrocyte
ASTROCYTE_OIDC_ACTOR_TYPE=user # optional, default "user"
  1. Client sends Authorization: Bearer <token> (RS256-signed by your IdP)
  2. Gateway extracts kid (key ID) from the JWT header
  3. Fetches the matching public key from ASTROCYTE_OIDC_JWKS_URL (cached ~10 min)
  4. Verifies RS256 signature, iss, and aud claims
  5. Maps claims to a full AstrocyteContext with structured identity
JWT claimMaps toDefault
subactor.id and part of principalRequired
astrocyte_actor_typeactor.typeASTROCYTE_OIDC_ACTOR_TYPE env var, or "user"
astrocyte_principalprincipal (explicit override)Computed as {actor_type}:{sub}
tid or tenant_idtenant_idnull
All other claimsactor.claims dictStringified; complex types JSON-serialized

Example: A token with {"sub": "abc-123", "astrocyte_actor_type": "agent", "tid": "tenant-1", "email": "bot@example.com"} produces:

AstrocyteContext(
principal="agent:abc-123",
actor=ActorIdentity(
type="agent",
id="abc-123",
claims={"email": "bot@example.com"},
),
tenant_id="tenant-1",
)
Terminal window
ASTROCYTE_OIDC_JWKS_URL=https://YOUR_DOMAIN.auth0.com/.well-known/jwks.json
ASTROCYTE_OIDC_ISSUER=https://YOUR_DOMAIN.auth0.com/
ASTROCYTE_OIDC_AUDIENCE=astrocyte

In Auth0 dashboard: create an API with identifier astrocyte. Configure your application to request this audience in the token.

Terminal window
ASTROCYTE_OIDC_JWKS_URL=https://keycloak.example.com/realms/YOUR_REALM/protocol/openid-connect/certs
ASTROCYTE_OIDC_ISSUER=https://keycloak.example.com/realms/YOUR_REALM
ASTROCYTE_OIDC_AUDIENCE=astrocyte

In Keycloak admin: create a client with astrocyte as the audience. Enable “Service Accounts” for machine-to-machine flows.

Terminal window
ASTROCYTE_OIDC_JWKS_URL=https://login.microsoftonline.com/YOUR_TENANT_ID/discovery/v2.0/keys
ASTROCYTE_OIDC_ISSUER=https://login.microsoftonline.com/YOUR_TENANT_ID/v2.0
ASTROCYTE_OIDC_AUDIENCE=api://astrocyte

Register an app in Azure AD, expose an API with scope, and configure tid claim mapping for multi-tenant scenarios.

Terminal window
ASTROCYTE_OIDC_JWKS_URL=https://YOUR_DOMAIN.okta.com/oauth2/default/v1/keys
ASTROCYTE_OIDC_ISSUER=https://YOUR_DOMAIN.okta.com/oauth2/default
ASTROCYTE_OIDC_AUDIENCE=astrocyte

In Okta admin: create an authorization server or use the default. Add astrocyte as an audience.

Terminal window
ASTROCYTE_OIDC_JWKS_URL=https://cognito-idp.REGION.amazonaws.com/POOL_ID/.well-known/jwks.json
ASTROCYTE_OIDC_ISSUER=https://cognito-idp.REGION.amazonaws.com/POOL_ID
ASTROCYTE_OIDC_AUDIENCE=YOUR_APP_CLIENT_ID

In Cognito: create a user pool, add an app client, and use the app client ID as the audience.

StatusDetailCause
401Bearer token requiredAuthorization header missing
401Invalid OIDC token: …Signature, issuer, audience, or expiry validation failed
401Token missing subsub claim absent
500ASTROCYTE_OIDC_JWKS_URL is not setEnv var not configured
500ASTROCYTE_OIDC_ISSUER and ASTROCYTE_OIDC_AUDIENCE are requiredEnv vars not configured

Authentication identifies who is calling. Access grants control what they can do. Enable access control in astrocyte.yaml:

access_control:
enabled: true
default_policy: owner_only # "owner_only" | "open" | "deny"
access_grants:
# Support bot can read and write to any shared bank
- bank_id: "shared-*"
principal: "agent:support-bot"
permissions: [read, write]
# Alice has full control of her bank
- bank_id: "user-alice"
principal: "user:alice"
permissions: [read, write, forget, admin]
# All users can read the public bank
- bank_id: "public"
principal: "*"
permissions: [read]
banks:
team-engineering:
access:
- principal: "agent:code-reviewer"
permissions: [read]
- principal: "user:*"
permissions: [read, write]

Top-level access_grants and per-bank banks.*.access are merged.

PermissionOperations
readrecall(), reflect()
writeretain()
forgetforget() with specific memory_ids or tags
adminBank config, forget(scope="all"), export/import
*All of the above
PolicyBehavior when no grants match
owner_onlyOnly the principal whose ID matches the bank pattern can access
openAllow all operations (no enforcement)
denyDeny all operations

When identity.obo_enabled: true and a context has both actor and on_behalf_of, effective permissions are the intersection of grants for both principals. This prevents privilege escalation when an agent acts on behalf of a user.


Admin routes (/v1/admin/*) use a separate token, independent of the auth mode:

.env
ASTROCYTE_ADMIN_TOKEN=admin-secret-here
Terminal window
curl http://localhost:8080/v1/admin/sources \
-H "X-Admin-Token: admin-secret-here"

If ASTROCYTE_ADMIN_TOKEN is not set, admin routes are unprotected.


VariableRequired byDescription
ASTROCYTE_AUTH_MODEAllAuth mode: dev, api_key, jwt_hs256/jwt, jwt_oidc
ASTROCYTE_API_KEYapi_keyShared secret for API key auth
ASTROCYTE_JWT_SECRETjwt_hs256Symmetric key for HS256 JWT verification
ASTROCYTE_JWT_AUDIENCEjwt_hs256 (optional)Expected aud claim
ASTROCYTE_OIDC_JWKS_URLjwt_oidcJWKS endpoint URL
ASTROCYTE_OIDC_ISSUERjwt_oidcExpected iss claim
ASTROCYTE_OIDC_AUDIENCEjwt_oidcExpected aud claim
ASTROCYTE_OIDC_ACTOR_TYPEjwt_oidc (optional)Default actor type (default: user)
ASTROCYTE_ADMIN_TOKENAdmin routes (optional)Token for /v1/admin/* routes