security: prepare scoped Playwright consumer registrations and owner delivery
Assistant: codex Assistant-Model: gpt-6-astra Assistant-Session: 01a1346b-72a4-7d40-b8bd-8b8ca346cfa2
This commit is contained in:
parent
30f0d27840
commit
5dd74dfbdf
5 changed files with 633 additions and 0 deletions
117
docs/playwright-registration.md
Normal file
117
docs/playwright-registration.md
Normal file
|
|
@ -0,0 +1,117 @@
|
|||
# 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.
|
||||
Loading…
Add table
Add a link
Reference in a new issue