apomesh-auth-providers
apomesh-auth-providers is the auth backend implementation plane: the
concrete SessionAuth and WorkerAuth backends that plug into the seams the
substrate defines. It is a plugin surface — multiple backends exist and the
operator picks one per plane at boot — so it sits beside the substrate
layering rather than inside it, next to apomesh-config. A backend’s one job
is to turn a presented credential into a resolved identity: a validated caller
the substrate can then authorize. Touch this crate to add or change how a
credential is validated (a new IDP claim shape, an mTLS identity rule); the
SessionAuth/WorkerAuth traits, the resolved-identity types, and the scope
enforcement all live elsewhere — see the identity &
authorization plane for the whole story.
Position in the workspace
Section titled “Position in the workspace”- Layer: auth / config support — a plugin plane beside the substrate layering. See Identity & authorization.
- Depends on: apomesh-config (the
AuthConfig+ per-backend config blocks) and apomesh-substrate (theSessionAuth/WorkerAuthtraits,AuthenticatedCaller,AuthError,PrincipalKind,TokenStore, and the runtime-token helpers). Plusjsonwebtoken+reqwestfor OAuth andx509-parserfor mTLS. - Consumed by:
apomesh-orchestrator-bin —
which calls both factories at startup and hands the resulting
Arc<dyn SessionAuth>to the gRPC daemon and the REST state — apomesh-orchestrator, and apomesh-rest-api.
What it owns
Section titled “What it owns”- The OAuth 2.0 / OIDC backend —
OAuthSessionAuthvalidates Bearer JWTs against the IDP’s JWKS: signature,iss,aud,exp, andnbf, with 60s leeway. Reads the operator-configured tenant, subject, and scopes claims off the token. - The JWKS machinery — a lock-free
ArcSwapOptioncache with TTL refresh and a one-shot forced refetch on akidmiss (IDP key rotation). Thejwks_urloverride and thejwks_host_headerHTTP/1.1 virtual-host override are the two backchannel knobs the OIDC-discovery follow-on will collapse into one concept. - The pre-shared API-key backend —
ApiKeySessionAuthmaps a static key set to(tenant, principal, scopes), compared in constant time (subtle::ConstantTimeEq) to blunt a timing oracle. - The mTLS backends —
MtlsSessionAuthandMtlsWorkerAuthinspect an already-validated leaf cert (tonic’s TLS layer validates the chain against the operator CA first) and extract the tenant / worker identity per a CN / SAN-DNS / SAN-URI rule. The shared cert-walk lives in the privatesanmodule so the two adapters cannot drift. - The runtime-token decorator —
TokenRoutingSessionAuthwraps the configured backend and routesamt_-prefixed bearer values to the substrate’sTokenStore, so platform-minted service tokens work under every backend,noneincluded. - The factory —
build_session_auth/build_worker_authconstruct the active backend fromAuthConfigand compose the runtime-token path.
It does not own the SessionAuth / WorkerAuth traits or the resolved
types (AuthenticatedCaller, PrincipalKind, ScopeSet) — those are the
substrate’s. The none-backend Null objects (NullSessionAuth,
NullWorkerAuth) live in apomesh-substrate on purpose, so the default daemon
never pulls in this crate’s jsonwebtoken / x509-parser graph. Scope
enforcement — checking a caller’s grants against a required scope — happens
at the substrate’s two trust-boundary prologues, not here; a backend only
resolves the granted scopes onto the caller. The Zitadel dev IdP is deploy
configuration, not part of this crate.
Public surface
Section titled “Public surface”build_session_auth— build the activeArc<dyn SessionAuth>fromAuthConfig+ aTokenStore; the runtime-token decorator is composed on unconditionally, so a daemon can never mint tokens it then refuses to authenticate.build_worker_auth— build the activeArc<dyn WorkerAuth>(Null or mTLS) fromAuthConfig.OAuthSessionAuth— the OAuth 2.0 / OIDC backend; resolves aPrincipalKind::Humancaller from the subject claim.ApiKeySessionAuth— the pre-shared-key backend; resolves aPrincipalKind::Servicecaller.MtlsSessionAuth— the mTLS session backend; identity from the validated leaf cert.MtlsWorkerAuth— the mTLS worker backend; extractsworker_idfrom the validated leaf cert.TokenRoutingSessionAuth— the runtime-token routing decorator over any inner backend.AuthProviderError— the factory’s construction-failure vocabulary (missing config block, backend init failure).
The daemon selects the backend from its config. [auth] names one
SessionAuth backend and one WorkerAuth backend, each with its own config
block:
[auth]backend = "oauth" # none | oauth | api-key | mtlsworker_backend = "none" # none | mutual-tls
[auth.oauth]issuer_url = "https://idp.example.com"audience = "apomesh"# jwks_url / jwks_host_header override the derived backchannel routeAt startup apomesh-orchestrator-bin calls build_session_auth(&config.auth, token_store) and build_worker_auth(&config.auth); the single
Arc<dyn SessionAuth> flows into both the gRPC daemon and the REST app state,
so both transports authenticate identically. Locally, the active profile
chooses the backend: the default dev profile runs backend = "none" (the
zero-config path), and the oauth profile wires the Zitadel dev IdP — see
The local stack.
Related
Section titled “Related”- Concepts: Identity & authorization — the principal, scope, and runtime-token story these backends implement.
- Operate: The local stack — the
nonevsoauthprofile posture. - Reference: apomesh-config (the
AuthConfigsurface), apomesh-substrate (the trait seams and resolved types), apomesh-orchestrator-bin (the startup wiring).