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

96 lines
6.2 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# 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) | **No**`S3BackendConfig` 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.