Files
artifact-store/docs/sts-credential-vending-assessment.md

6.2 KiB
Raw Blame History

STS Credential Vending Assessment for NetKingdom

Status: assessment complete (ARTIFACT-STORE-WP-0007 D7.3) Date: 2026-07-02 Upstream baseline: net-kingdom/docs/object-storage-sts-credential-vending.md (NK-WP-0007, 2026-05-18) — this assessment specializes that architecture for artifact-store and records the current-state inventory it asks for.

1. Current object-storage credential inventory

Consumer Credential path today Temporary-credential ready?
artifact-store S3 backend Static key pair via ARTIFACTSTORE_S3_ACCESS_KEY_REF / ARTIFACTSTORE_S3_SECRET_KEY_REF (file/env refs, no plaintext in config) NoS3BackendConfig has no session_token field and aioboto3.Session is constructed without aws_session_token (src/artifactstore/storage/backends/s3.py); STS credentials cannot be consumed until D7.4 lands
NetKingdom CNPG backups (net-kingdom-pg-backup-s3) Documented as a static kubectl create secret generic --from-literal key pair in sso-mfa/k8s/postgresql/README.md; not yet provisioned — backups are parked "until object storage is available" No — static by design today; should adopt the vending flow (or at minimum an ExternalSecret lane) when object storage is provisioned
MinIO compatibility harness (make test-minio / test-minio-local) One-run generated throwaway root credentials, local container only N/A — dev double, never a production path

No other live S3/MinIO credential consumers were found in net-kingdom or artifact-store. The most important inventory conclusion: nothing is production-live yet, so the vending architecture can be adopted without a migration burden — the CNPG backup lane should start on the target pattern rather than shipping static keys first.

2. Can Keycloak / Authelia / local-identity act as the OIDC IdP for MinIO AssumeRoleWithWebIdentity?

MinIO's STS AssumeRoleWithWebIdentity accepts any OIDC JWT whose issuer is configured in MinIO's identity-provider settings and whose claims map to a MinIO policy. Assessment per NetKingdom issuer:

  • key-cape (lightweight mode) — yes, and it is the preferred first issuer: it already issues IAM Profile v0.2 tokens with OIDC discovery + JWKS (proven by the Core Hub verifier integration test, CUST-WP-0025-T03). MinIO consumes the discovery URL directly.
  • Keycloak (expanded mode) — yes; standard, widely documented MinIO OIDC pairing. This is the production/enterprise-federation issuer per the NetKingdom baseline; not yet deployed (NK-WP-0001 Keycloak was cancelled as superseded, so key-cape leads until enterprise federation is needed).
  • Authelia — technically an OIDC provider, but it is the NetKingdom session/portal SSO layer and does not issue IAM Profile v0.2 claims (tenant, principal_type, assurance). Using it as a storage IdP would bypass the IAM Profile contract. Do not use as the vending issuer.
  • local-identity — dev/bootstrap contexts only, per the baseline's local-dev restrictions: only explicitly configured dev vending instances may accept it, and minted credentials must be confined to local/sandbox object stores.

Important nuance from the baseline: consumers should not hit MinIO STS directly with raw IdP tokens. The credential-vending service verifies the IAM Profile and asks flex-auth for the decision first; MinIO's own claim-to-policy mapping is then deliberately coarse (one policy per tenant/prefix class), keeping authorization in flex-auth rather than in MinIO policy JSON.

3. Target architecture (artifact-store specialization)

Follow the NetKingdom baseline flow (IAM Profile token → vending service → flex-auth decision → backend exchange → temporary credentials). The artifact-store-specific bindings:

Element Binding
Issuer key-cape lightweight mode first; Keycloak expanded mode when enterprise federation arrives; local-identity for sandbox only
Audience the credential-vending service audience (not artifact-store, not MinIO) — aud per IAM Profile v0.2
Role/policy mapping flex-auth vocabulary from the baseline: tenant, protected-system=object-storage, bucket, prefix, actions (read/write/list), TTL; MinIO side keeps one coarse policy per tenant-prefix class
Expiration default lease 1560 min with refresh-before-expiry + jitter in the consumer; TTL bounds enforced by flex-auth (proven pattern: ttl_out_of_bounds denial in the FLEX-WP-0007 smoke)
Revocation short TTLs are the primary control; for immediate cuts, disable the MinIO policy or the vending grant; OpenBao lease revocation applies only to broker-held parent material
Audit vending service emits the baseline's audit event (issuer, sub, tenant, decision id, backend, TTL, non-secret request ids); OpenBao audit covers parent-credential access
Break-glass platform-control-plane path per the baseline: short-lived, post-event review record mandatory; never a tenant-plane shortcut

artifact-store consumer work (feeds D7.4)

  1. Add session_token: str | None to S3BackendConfig and pass aws_session_token into aioboto3.Session.
  2. Add ARTIFACTSTORE_S3_SESSION_TOKEN_REF (and optionally ARTIFACTSTORE_S3_CREDENTIAL_EXPIRATION_REF) alongside the existing refs, with atomic refresh of all three values.
  3. Support the delivery modes from the baseline in priority order: mounted files refreshed by a controller/sidecar first (fits the current _REF file pattern), credential_process for CLI/batch use later.

Sequencing recommendation

  1. D7.4: session-token consumer support (small, local, no deployment gate).
  2. Vending service + flex-auth vocabulary (NetKingdom/flex-auth owned; artifact-store is a consumer, not the owner).
  3. Wire the CNPG backup lane and artifact-store deployment to the vending flow when Railiance provisions the production object store — do not ship static production keys in the interim.

Non-goals confirmed

  • artifact-store does not own identity, authorization, or secret custody (baseline ownership table).
  • OpenBao is not the object-storage authorization engine; it holds parent material and audit only.
  • MinIO policy JSON is not the canonical tenant policy model; flex-auth is.