Files
stack/docs/PRDs/2026-08-31_PRD_rev1/AUTHN.1-auth-accounts.md
T
jason.woltje ad21ad7ac5
ci/woodpecker/pr/ci Pipeline failed
docs: ratify PRD rev1 — consolidated bundle, permanent shim, rev0 archived
Ratifies the Mosaic Stack PRD rev1 (Jason Woltje, 2026-09-01) as project
source of truth and installs the GOV.1 lifecycle model:

- docs/PRD.md becomes a permanent shim (kind: shim, current_rev ->
  docs/PRDs/2026-08-31_PRD_rev1/). Its path never changes again.
- docs/PRDs/2026-08-26_PRD_rev0/PRD.md archives the 2026-08-26 North Star
  verbatim (sha256 60cc2f98...36afdf unchanged). Archive, never delete.
- docs/PRDs/2026-08-31_PRD_rev1/ is the frozen rev1 bundle: 18 sectioned
  documents (VIS, DATA, AUTHN, AUTHZ, SEAT, ROLE, HARN, PROV, SESS, UI, CLI,
  GOV.1-5) consolidating rev0 D1-D15, the fleet north star, the agent-runtime
  L1/L2 contracts and the control-plane-surfaces lane findings, with a single
  decision map (GOV.3) and a closed open-questions frontier (GOV.5, grill
  rounds 1-8). Drafting inputs (_source-* snapshots) are not shipped.

Consequences of the ratified rulings carried in the same change:

- Q-T1 (ruling B, "shipped but frozen"): D3 amended in GOV.3/VIS.1;
  federation M1-M3 acknowledged as shipped behind tier === 'federated',
  excluded from the v1 bar and frozen, with a security re-audit gate before
  any resumption. docs/MISSION-MANIFEST.md, docs/federation/MISSION-MANIFEST.md
  and docs/scratchpads/mvp-20260312.md get status: superseded + banners
  (content preserved verbatim); docs/guides/deployment.md gains a
  "Relationship to the PRD (D15)" section. NORTH_STAR.yaml adds dormant
  workstream M (projects no goals by design); NORTH_STAR.md regenerated.
- Q-G2 (distinct registry prefixes): every citation of the operator
  DECISION-REGISTER in the bundle reads OD-nn; the stack registry stays
  D1-D15; L1-Dnn/L2-Dnn untouched. Prefix rule recorded in GOV.1.

Follow-ups (not in this PR): CI parity drift-gate witness (Q-C1); brain-side
DECISION-REGISTER rename to OD- with redirect table on its next touch.
2026-09-01 18:32:14 -05:00

4.3 KiB

id, status, ratified
id status ratified
AUTHN.1 ratified 2026-09-01 (Jason Woltje; PRD rev1 ratification PR)

AUTHN.1 — Authentication accounts

Agent-side provider credentials: the accounts seats use to reach providers. (Human login identity is D10 territory — better-auth as system of record — and is out of this section's scope.)

Authentication configuration surface (WebUI page + CLI)

Control Notes
in-browser OAuth establishment the OAuth flow runs in-browser; whether the backing terminal flow is tmux-bridged is open: GOV.5-open-questions Q-N1
configured accounts list provider, mode (OAuth/API), status, holder
force renew
deactivate deactivated accounts drop out of every seat/harness selector
allowed harnesses which harnesses may use this account

Custody rules

  • Secrets live with the credential broker (OpenBao/Vault or flat files per deployment mode — D3), never in the brain tree, never in manifests, never in Postgres records. Enforced role manifests declare credentials: {store: none, providerTokens: denied} — the enforced roles hold no credentials at all; accounts are a launcher/broker concern.
  • Multi-account per provider is a requirement (onboarding D4 already captures multi-account enrollment).
  • Account shape in the seat record (single account vs per-provider map) is open: GOV.5-open-questions Q-D2.

Credential-broker custody rules (pulled 2026-08-31, generalized from the vault draft)

  • Reads require a token scoped to the needed paths; provisioning and writes go through a declared channel with documented purpose. An ordinary role never mints credentials or creates production paths.
  • Canonical secret path: environment / service / component / secret-name, lowercase kebab-case, nothing sensitive encoded in the path; environments never cross-reference each other's mounts. Standard field names (username/password, token, host/port/url).
  • Only the needed field is extracted into the consuming process; values are never echoed to logs or transcripts — read success is proven by field presence and digest, never by printing the value.
  • Least privilege, short-lived tokens, no local copies, immediate rotation on compromise; every access audited by the broker.

E2 inputs (triage 2026-08-31; see GOV.2-docs-inventory)

Canonical ground truth: ADMIN-GUIDE/security/sso-providers.md (D10 ground truth: better-auth + Authentik/WorkOS/Keycloak OIDC). Pending pulls: DRAFT S2 identity-lifecycle.md (D10 + the #1430 bootstrap fix) and custody-schema.md; brain docs/guides/proposed/operations/vault.md (credential-broker custody rules this section states without operational detail).

S2 contract feed (extraction 2026-08-31)

Full extraction record: lane S2-EXTRACTION-2026-08-31.md (per-contract cores, dependency edges, ruling cross-checks). Pulls binding on this section (identity-lifecycle, contract 4, plus wizard AUTHN clauses):

  • better-auth tables are the only account system of record (D10); IdPs are login methods only; account creation grants nothing.
  • registration_mode open/invite/closed, defaults closed post-bootstrap, forced closed during the epoch, enforced at a better-auth hook.
  • Bootstrap/first-admin invariant (#1430): zero-to-one-admin exactly once per epoch, one atomic transaction, durable fail-closed bootstrap_state, re-runnable; first-admin-via-SSO runs as a bootstrap-writer transaction, never JIT. v1 first admin is password-only — a disclosed PRD deviation.
  • JIT defaults OFF per-provider always; JIT users get member, never elevated; role/authorization attributes are never mapped from IdP claims. Linking keyed (issuer, subject); explicit linking = step-up reauth ≤10 min; automatic linking gated by off-by-default trusted_for_linking + verified email.
  • Deactivation (ban) must bound all entry paths — live defect: the admin-bearer-token path does not check banned status. Deletion deferred; the existing hard-delete endpoint and mosaic auth users delete are mandated for removal.

Seat auth shape ruling (Q-D2, Jason 2026-09-01)

Per-provider map in profile.json, values are credential-broker references — never secret material. The broker custody rules above govern resolution; extraction stays field-scoped and digest-proven.