Skip to content

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.

  • 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 (the SessionAuth / WorkerAuth traits, AuthenticatedCaller, AuthError, PrincipalKind, TokenStore, and the runtime-token helpers). Plus jsonwebtoken + reqwest for OAuth and x509-parser for 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.
  • The OAuth 2.0 / OIDC backendOAuthSessionAuth validates Bearer JWTs against the IDP’s JWKS: signature, iss, aud, exp, and nbf, with 60s leeway. Reads the operator-configured tenant, subject, and scopes claims off the token.
  • The JWKS machinery — a lock-free ArcSwapOption cache with TTL refresh and a one-shot forced refetch on a kid miss (IDP key rotation). The jwks_url override and the jwks_host_header HTTP/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 backendApiKeySessionAuth maps a static key set to (tenant, principal, scopes), compared in constant time (subtle::ConstantTimeEq) to blunt a timing oracle.
  • The mTLS backendsMtlsSessionAuth and MtlsWorkerAuth inspect 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 private san module so the two adapters cannot drift.
  • The runtime-token decoratorTokenRoutingSessionAuth wraps the configured backend and routes amt_-prefixed bearer values to the substrate’s TokenStore, so platform-minted service tokens work under every backend, none included.
  • The factorybuild_session_auth / build_worker_auth construct the active backend from AuthConfig and 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.

  • build_session_auth — build the active Arc<dyn SessionAuth> from AuthConfig + a TokenStore; 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 active Arc<dyn WorkerAuth> (Null or mTLS) from AuthConfig.
  • OAuthSessionAuth — the OAuth 2.0 / OIDC backend; resolves a PrincipalKind::Human caller from the subject claim.
  • ApiKeySessionAuth — the pre-shared-key backend; resolves a PrincipalKind::Service caller.
  • MtlsSessionAuth — the mTLS session backend; identity from the validated leaf cert.
  • MtlsWorkerAuth — the mTLS worker backend; extracts worker_id from 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 | mtls
worker_backend = "none" # none | mutual-tls
[auth.oauth]
issuer_url = "https://idp.example.com"
audience = "apomesh"
# jwks_url / jwks_host_header override the derived backchannel route

At 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.