Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
117 lines
6.7 KiB
Markdown
117 lines
6.7 KiB
Markdown
# Playwright registration owner contract
|
|
|
|
Source preparation under NK-WP-0050; live custody, rollout and consumer acceptance
|
|
remain open. Implements the registration part of RPF-WP-0056 and
|
|
CUST-WP-0080-T05. The existing browser SecurityCaseType remains unchanged: its
|
|
HTTPS/standard-scope admission does not cover this loopback/custom-scope use.
|
|
No case acceptance record is fabricated or borrowed from Forgejo/OpenBao.
|
|
|
|
## Prepare the non-secret records
|
|
|
|
Run `python3 sso-mfa/k8s/keycape/playwright-registration.py` for the public
|
|
client, or add `--agents <identity-references.json>` for the complete proposed
|
|
Playwright agent inventory. The latter is an array with one object per existing
|
|
registered identity:
|
|
|
|
```json
|
|
[
|
|
{
|
|
"agent_id": "test-agent",
|
|
"service_subject": "service:test-agent:platform",
|
|
"tenant": "tenant:test",
|
|
"identity_record": "synthetic/agent-record.json"
|
|
}
|
|
]
|
|
```
|
|
|
|
This example is synthetic; it is not an admitted consumer. The identity owner
|
|
must confirm each real record, subject, tenant and agent assignment. A reference
|
|
string is not evidence of registration. Initial eligibility already covers all
|
|
identified platform humans and coding agents; no new membership decision is
|
|
needed. The compiler does not provision identities or retrieve/mint credentials.
|
|
|
|
| Field | Public human client | Each coding agent |
|
|
| --- | --- | --- |
|
|
| client ID | `playwright-cli` | `playwright-agent-<agent_id>` |
|
|
| grant | authorization code, public PKCE | client credentials, confidential |
|
|
| audience | `playwright-kubernetes` | `playwright-kubernetes` |
|
|
| scope | `openid profile groups playwright:connect` | `playwright:connect` |
|
|
| redirect | exact `http://127.0.0.1:18764/callback` | none |
|
|
| subject/tenant | existing directory user and tenant | exact registered subject/tenant supplied by owner |
|
|
| role | existing human roles | only `coding-agent` |
|
|
| lifetime | existing issuer setting, explicit and at most one hour | 15 minutes |
|
|
|
|
The public client has no per-client lifetime override; KeyCape supports that only
|
|
for client-credentials clients. Existing issuer lifetime outside the accepted
|
|
bound refuses preparation and needs owner reconciliation; this tool does not
|
|
change every client's lifetime. No public tenant override or MFA opt-out is added.
|
|
The callback, dedicated audience and custom scope match Platform's candidate.
|
|
The resource uses access tokens; ID tokens retain the client audience.
|
|
|
|
Each agent gets a distinct proposed env binding from
|
|
`keycape-<client-id>-client`, key `client-secret`, to
|
|
`KEYCAPE_<CLIENT_ID_WITH_UNDERSCORES>_CLIENT_SECRET`. These names describe a
|
|
proposed delivery contract, **not existing Secrets or admitted custody**. Platform
|
|
must bind an exact OpenBao/ESO and consumer delivery route with its own source
|
|
task and acceptance. No existing OpenBao client or secret is reused. Secret
|
|
values must never enter this identity-reference file, Git, command arguments,
|
|
coordination messages or receipts.
|
|
|
|
## Registry and activation boundary
|
|
|
|
The pure `prepare_registry(secret, identities, operation)` adapter reuses
|
|
`keycape-client.py`'s byte-preserving insertion/removal. It validates the entire
|
|
inventory first, refuses differing existing records, ambiguous YAML, duplicate
|
|
IDs, shared secret references and unreviewed registrations for this dedicated
|
|
audience. An identical registration is a no-op. A separate existing OpenBao
|
|
registration for the same agent subject is preserved, with its distinct audience
|
|
and secret reference. Unrelated configuration, including signing material, is
|
|
unchanged. The encoded result contains private registry data and must stay inside
|
|
the protected activation process; the CLI never accepts or emits that registry.
|
|
|
|
This is not a live apply command. NK-WP-0050-T02 must finish the exact owner
|
|
activation path using existing registry/Deployment operations:
|
|
|
|
1. Bind verified identity inventory and source digests to the proposal. Obtain
|
|
the governed per-agent custody and delivery references from Platform.
|
|
2. Pin current cluster, issuer image and object identities. Read the registry
|
|
only within the existing protected owner execution path. Run the actual
|
|
pinned KeyCape `check-config` on live and proposed configurations, with the
|
|
exact Deployment env names and policy-store mode; suppress private diagnostics.
|
|
3. Prepare UID/resource-version/data-bound registry mutation and exact env
|
|
bindings. Preserve all unrelated data and authentication methods. Retain
|
|
created-only provenance, restart prerequisites, readback and guarded rollback
|
|
before proposing any live action. A compare-and-swap conflict means reconcile,
|
|
never replay a stale whole registry.
|
|
4. Obtain the scoped live action disposition under the existing supervision
|
|
rules, execute its exact revision, verify config/env/image/readiness and
|
|
existing human/service login. No new runtime authority comes from this file.
|
|
|
|
`operation=remove` is an exact inventory removal proposal, not automatic
|
|
rollback: the activation adapter must remove only registrations it created,
|
|
preserve pre-existing identical entries and refuse intervening drift. Keep
|
|
custody material until recovery/retention requirements are met. Disabling/removing
|
|
registration stops new issuance after the issuer loads the change; issued JWTs
|
|
remain valid until expiry, and established connections need separate termination
|
|
through the transport owner. No immediate global revocation is claimed.
|
|
|
|
## Verification and completion
|
|
|
|
Python tests exercise preservation, add/no-op/remove, lifetime bounds, identity
|
|
conflicts, distinct credentials and contained invalid-input output. The native
|
|
Go fixture `tests/playwright_registration_native_test.go` is copied into a
|
|
disposable committed KeyCape checkout at `src/internal/authclient/` and consumes
|
|
the merged synthetic configuration through `PLAYWRIGHT_SYNTHETIC_CONFIG`.
|
|
It loads the config and domain registrations, performs native token/JWKS
|
|
exchanges for both client kinds, and checks dedicated claims, wrong secret,
|
|
scope, audience, signature, PKCE and callback refusals. It uses synthetic users
|
|
and seeded authorization sessions; it does not prove upstream login, production
|
|
image compatibility, native Kubernetes CEL validation or consumer eligibility.
|
|
|
|
T03 needs actual issuer issuance and native API allow/deny receipts, one real
|
|
human and one real registered coding agent independently running Platform's
|
|
consumer command and provider responsive/keyboard trial, renewal, revocation and
|
|
active connection termination. Cluster authentication and ops-bridge transport
|
|
remain their owners' implementations. Platform/provider must accept the receipts
|
|
before managed discovery is published. Same-image abrupt provider recovery is
|
|
already evidenced; cross-version rollback is still explicitly unproven.
|