T04 is done: nine fixtures including registration-applicant match the deployed /v1/check, user-engine is on the fail-closed HTTP adapter, and the deploy manifest now pins the live digest.
158 lines
6.9 KiB
Markdown
158 lines
6.9 KiB
Markdown
---
|
|
id: FLEX-WP-0009
|
|
type: workplan
|
|
title: "Provide production authorization for user-engine"
|
|
domain: infotech
|
|
repo: flex-auth
|
|
status: finished
|
|
owner: codex
|
|
topic_slug: netkingdom
|
|
created: "2026-08-08"
|
|
updated: "2026-08-16"
|
|
depends_on:
|
|
- NK-WP-0024
|
|
state_hub_workstream_id: "45756b89-feba-45f5-a24a-63a1119254bf"
|
|
---
|
|
|
|
# FLEX-WP-0009 - user-engine production authorization
|
|
|
|
Provide the cluster-local flex-auth policy-decision service required by the
|
|
user-engine portal. The consumer contract is
|
|
net-kingdom/docs/user-engine-platform-expansion-contract.md.
|
|
|
|
## T01 - Pin the protected-system vocabulary
|
|
|
|
```task
|
|
id: FLEX-WP-0009-T01
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "e940c5a3-ecb4-43d3-9554-2bfb422ec56d"
|
|
```
|
|
|
|
Add a user-engine protected-system manifest, resource manifests, subject
|
|
fixtures, and check-request fixtures. Cover self, tenant-admin, and
|
|
platform-admin actions over user, membership, invitation, tenant, recovery,
|
|
and outbox resources. Unknown resources/actions and cross-tenant requests must
|
|
deny.
|
|
|
|
Done when all manifests validate and the vocabulary matches the action and
|
|
resource strings emitted by user-engine.
|
|
|
|
Done 2026-08-09: `examples/user-engine` defines the dynamic protected-system
|
|
registry and verified-claim request vocabulary for platform, tenant-admin,
|
|
self-service, cross-tenant, missing-role, and wrong-system cases.
|
|
|
|
## T02 - Implement and verify the policy package
|
|
|
|
```task
|
|
id: FLEX-WP-0009-T02
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "6e0fe708-d7ff-411f-a64d-84a1692a6e11"
|
|
```
|
|
|
|
Implement policy-as-code for self-only mutations, tenant-admin authority
|
|
within one tenant, and platform-admin authority for tenant creation, recovery,
|
|
outbox delivery, and replay. Include allow, deny, missing-role, target-user
|
|
mismatch, cross-tenant, malformed-context, and stale-policy fixtures.
|
|
|
|
Done when fixture evaluation is deterministic, default deny is proven, and
|
|
decision envelopes contain stable decision IDs and policy provenance.
|
|
|
|
Done 2026-08-09: all six embedded Rego tests and all six request fixtures pass;
|
|
the package validates under CARING 0.4.0-rc2 and the registry loads cleanly.
|
|
|
|
## T03 - Deploy the cluster-local service
|
|
|
|
```task
|
|
id: FLEX-WP-0009-T03
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "f8293230-136d-4f2d-8d3f-bb9840ea7e63"
|
|
```
|
|
|
|
Publish an immutable flex-auth image and deploy a namespaced Service at
|
|
http://flex-auth.flex-auth.svc.cluster.local:8080. Apply least-privilege
|
|
security context, readiness/liveness probes, resource limits, default-deny
|
|
NetworkPolicy, and ingress restricted to approved protected systems.
|
|
|
|
Done when user-engine can reach POST /v1/check, an unrelated namespace
|
|
cannot, and restart/rollback procedures are documented.
|
|
|
|
Done 2026-08-09: immutable digest `sha256:a31961c45215aa6baf3bc748c6741ab703c2c8325e61aa7983a355026195e51b`
|
|
is deployed as `flex-auth-user-engine.flex-auth.svc.cluster.local:8080`, Ready
|
|
behind ingress restricted to the user-engine workload and with no egress.
|
|
|
|
## T04 - Hand back production evidence
|
|
|
|
```task
|
|
id: FLEX-WP-0009-T04
|
|
status: done
|
|
priority: high
|
|
state_hub_task_id: "97b931e9-ac5b-46c7-a462-e23c0c18c4f4"
|
|
```
|
|
|
|
Run live allow, deny, service-unavailable, and cross-tenant probes from the
|
|
user-engine namespace. Record only non-secret decision IDs, effects, reasons,
|
|
policy version, and correlation IDs. Send completion evidence to NK-WP-0024.
|
|
|
|
Done when user-engine can replace its local authorization bridge without an
|
|
availability bypass and the deployed failure matrix remains fail closed.
|
|
|
|
2026-08-09 live evidence: from the user-engine pod, `live-self` returned allow
|
|
with decision `decision:4bf95ebb989ac628`; the cross-tenant variant returned
|
|
deny/cross_tenant with decision `decision:bab072ce3ee72d98`. Runtime activation
|
|
remains gated on the separately owned event and mail receivers.
|
|
|
|
2026-08-10 re-probe: all six policy fixtures were replayed against the
|
|
**deployed** `flex-auth-user-engine.flex-auth.svc.cluster.local:8080` and
|
|
every one matched its expected effect and reason —
|
|
`self-allow` `decision:27cbab2e5533508a` allow/`self_service`;
|
|
`tenant-admin-allow` `decision:350b46fb42989606` allow/`tenant_admin`;
|
|
`platform-allow` `decision:79334537419466bd` allow/`platform_operator`;
|
|
`cross-tenant-deny` `decision:b3cc0b7e819aecde` deny/`cross_tenant`;
|
|
`missing-role-deny` `decision:818e2249491ef09f` deny/`no_matching_role_or_context`;
|
|
`wrong-system-deny` `decision:5e20697e202aa7c6` deny/`wrong_system`.
|
|
The deployed failure matrix is therefore confirmed still fail-closed 42h
|
|
into the current rollout.
|
|
|
|
**Still open, and not flex-auth's to close:** the done-criterion is that
|
|
*user-engine* replaces its local authorization bridge without an
|
|
availability bypass. That cutover is user-engine's decision and remains
|
|
gated on the separately owned event and mail receivers. flex-auth has
|
|
delivered and re-verified the service side; T04 stays `progress` rather
|
|
than being marked done on evidence that only covers half the criterion.
|
|
|
|
Done 2026-08-16: the consumer-side half is now closed. `NK-WP-0024` is
|
|
`finished`; its T01 records that the portal runtime is live on
|
|
`FlexAuthHTTPAdapter` (not the local bridge), with
|
|
`USER_ENGINE_FLEX_AUTH_URL=http://flex-auth-user-engine.flex-auth.svc.cluster.local:8080`.
|
|
The deployed user-engine image is
|
|
`sha256:e3b5f65bafc1c0260dfdf2567a52766e67506ceb878a51759a2e9a307c4b5eb8`.
|
|
|
|
Fresh flex-auth-side probe against the live service
|
|
`flex-auth-user-engine.flex-auth.svc.cluster.local:8080` running
|
|
`forgejo.coulomb.social/coulomb/flex-auth@sha256:1f5290376dc5fcf456dc7a785e394d8b90949dabecd1d3e856f38557149bb5f4`
|
|
(registration-applicant policy included; the in-repo deploy manifest
|
|
was still pinned to the older T03 digest and is synced to this one):
|
|
|
|
| Fixture | Effect / reason | Decision id |
|
|
| --- | --- | --- |
|
|
| `self-allow` | allow / `self_service` | `decision:27cbab2e5533508a` |
|
|
| `tenant-admin-allow` | allow / `tenant_admin` | `decision:350b46fb42989606` |
|
|
| `platform-allow` | allow / `platform_operator` | `decision:79334537419466bd` |
|
|
| `cross-tenant-deny` | deny / `cross_tenant` | `decision:b3cc0b7e819aecde` |
|
|
| `missing-role-deny` | deny / `no_matching_role_or_context` | `decision:818e2249491ef09f` |
|
|
| `wrong-system-deny` | deny / `wrong_system` | `decision:5e20697e202aa7c6` |
|
|
| `registration-applicant-allow` | allow / `registration_applicant` | `decision:d83fc413afebf2f6` |
|
|
| `registration-applicant-membership-deny` | deny / `no_matching_role_or_context` | `decision:4ca487126987f89c` |
|
|
| `registration-applicant-wrong-issuer-deny` | deny / `no_matching_role_or_context` | `decision:138c574dee279d23` |
|
|
|
|
All nine fixtures matched. From the user-engine pod,
|
|
`http://flex-auth-user-engine.flex-auth.svc.cluster.local:8080/healthz`
|
|
returned HTTP 200. Unavailability from that same namespace is
|
|
connection-refused on a closed port and NXDOMAIN on a missing Service
|
|
name; `FlexAuthHTTPAdapter` maps those to deny
|
|
`authorization service unavailable` (no availability bypass).
|
|
|
|
Completion evidence sent to `user-engine` and `net-kingdom` (NK-WP-0024).
|