Commit graph

57 commits

Author SHA1 Message Date
custodian-sync
ff87f32ef4 chore(consistency): sync task status from DB [auto]
Updated by fix-consistency on 2026-08-18:
  - FLEX-WP-0015-T02: progress → wait
2026-08-18 07:28:38 +02:00
ac02445206 Ask ops-warden how /v1/check should authenticate callers; T02 waits
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 22:04:04 +02:00
f2b3eeefd8 Review NetKingdom Tenancy Posture v0.1 and declare flex-auth posture
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
Publishes tenancy.yaml (I1 A0 E2 P n/a R n/a, enables A3), the review
answering rapp-postgres's three asks, and FLEX-WP-0015 to close the gaps.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-17 18:09:59 +02:00
79582870c0 Pin flex-auth-tenant-engine to the nine-action policy image
All checks were successful
CI Smoke / container-smoke (push) Successful in 1s
CI Smoke / host-smoke (push) Successful in 0s
Build and Publish Container Image / build-and-push (push) Successful in 35s
CI digest sha256:1bf060e6 (main-f304688) is live. Seven pre-existing
actions still allow; guardrail.read/set match the FLEX-WP-0014 split.
user-engine pin unchanged. Rollback target is sha256:9320df39.
2026-08-16 09:57:07 +02:00
4a4eab524b Finish FLEX-WP-0011 after drain-plan row 23 correction
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
T03 is done: the-custodian placement register now lists flex-auth on
railiance01 as on target (c377f0d). T01/T02 were already complete.
2026-08-16 09:45:59 +02:00
a98b5fc063 chore(consistency): record FLEX-WP-0014 hub IDs
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
C-06 registered the guardrail workplan and wrote state_hub_workstream_id
plus the four task ids back into the file.
2026-08-16 02:47:13 +02:00
f304688d72 Authorize tenant-engine guardrail read and set actions
All checks were successful
Build and Publish Container Image / build-and-push (push) Successful in 39s
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
FLEX-WP-0014. Package tenant-engine.write-api.mutate v1 now carries
nine actions: tenant.guardrail.read and tenant.guardrail.set on
resource type guardrail, verbatim from tenant-engine's mapping.

The read/write split is used now: flex-auth may read ceilings and is
denied action_not_granted on set; tenant-engine may do both. 17/17
Rego tests and 23/23 fixtures pass. Live e2e against a real
tenant-engine FlexAuthWriteAuthorizer matches.

In source only; production still serves the seven-action 9320df39 pin.
2026-08-16 02:46:25 +02:00
8563c17a9f chore(consistency): record FLEX-WP-0013 hub IDs
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 2s
C-06 registered the restore workplan and wrote state_hub_workstream_id
plus the three task ids back into the file.
2026-08-16 02:37:48 +02:00
87f114f036 Restore flex-auth-tenant-engine to the seven-action policy image
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 32s
FLEX-WP-0013. Production had been rolled back to sha256:c25fc34a
(four actions), so tenant.update / tenant.retire / tenant.reactivate
denied unknown_action. Re-pin and apply the previously-live
sha256:9320df39 image (e9911eb). Live probe after restore: all seven
actions allow; misspelled action and unknown subject still deny.
user-engine pin unchanged. TEN-WP-0006 guardrail actions not added.
2026-08-16 02:36:56 +02:00
1d58f13eb8 Add Railiance staged-promotion overlay for flex-auth
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
FLEX-WP-0011 T01/T02: railiance.app.v1 contract, independently pinned
Helm values for tenant-engine and user-engine, isolated canary cycle
(deploy/observe/promote/rollback), and emergency kubectl path retained.
T03 waits on the custodian drain-plan row.
2026-08-16 01:32:31 +02:00
804251514c chore(consistency): record FLEX-WP-0009 finished and 0012 hub IDs 2026-08-16 01:18:17 +02:00
4dcc69b41b Close FLEX-WP-0009 with live user-engine policy evidence
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 53s
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.
2026-08-16 01:16:23 +02:00
693136edbc Plan credential-grant authorization for railiance-platform (FLEX-WP-0012)
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
Opens the State Hub capability request 893ff109, unanswered since
2026-07-02. Drafted as proposed/P3 rather than as the blocker it was
filed as, because two of its premises no longer hold:

- It is not blocking anyone. railiance-platform re-scoped and closed
  RAILIANCE-WP-0005-T07 the same day it filed the request; WP-0005 is
  finished and their grant catalog already enforces TTL, actor-type,
  purpose and delivery-mode bounds locally. This buys defence in depth
  and central decision records, not unblocking.
- The stated technical blocker is wrong. The request says the CARING
  /v1/check schema cannot express TTL, purpose or delivery mode; the
  ops-warden package in this repo already denies ttl_out_of_bounds by
  reading input.context.ttl_hours against resource.attributes. CARING
  constrains descriptor vocabulary, not the request payload.

The real gap is narrower: no credential-grant policy package exists, and
the helper's flat payload/response shape differs from CheckRequest. Its
endpoint path is configurable, so no bespoke endpoint is strictly
required. T01 makes the adapter-vs-consumer-mapping call an explicit,
jointly-agreed decision rather than a default.

Flags two things worth knowing before anyone implements: the helper sends
requested_ttl as a duration string while the ops-warden precedent compares
numeric hours (mis-parsing it would fail open on the check that matters
most), and without --require-flex-auth the helper continues by local
preauthorization when flex-auth is unreachable -- a different posture from
the tenant-engine and ops-warden gates.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 13:38:41 +02:00
3dc6223cc2 Roll flex-auth-tenant-engine onto the FLEX-WP-0010 policy image
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 2s
CI-built image from e9911eb, digest
sha256:9320df394a642eff24da8af4a0ee8886a7bb78b0f14d8ee1deeb30ea8eeeaba7,
verified in a throwaway container before pinning and then probed again
against the live Service after rollout:

  tenant.retire    allow write_api_policy_matched  decision:491bbef2db999c02
  tenant.create    allow write_api_policy_matched  decision:fa3ba90e9cccb5aa
  tenant.retired   deny  unknown_action            decision:c5ee185de439ffe5
  unknown subject  deny  unknown_subject           decision:a98c59c6a34f84ad

tenant.retire has flipped from deny unknown_action to allow in
production, which is what TEN-WP-0005-T05 was waiting on.

Only flex-auth-tenant-engine was rolled. flex-auth-user-engine stays
pinned to a31961c4 -- its policy is unchanged and there is no reason to
move it. Previous tenant-engine digest kept in the runbook as the
rollback target.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 10:41:25 +02:00
e9911eb77f Publish images via CI; file staged-promotion overlay debt
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
Build and Publish Container Image / build-and-push (push) Successful in 52s
flex-auth had no image workflow, so its production images were hand-built
on a workstation and pushed with workstation credentials -- an artifact
whose provenance was someone's working tree rather than a forge revision.
Ports activity-core's canonical image.yaml: the container-build runner
fetches a tarball of the pushed commit, builds, and pushes :latest and
:main-<short-sha>, then reports the immutable digest for the rollout step.

examples/** is a build-trigger path on purpose -- policy packages are
COPYed into the image and there is no hot reload, so a policy change is
an image change.

Runbook updated to say plainly that images are not built on workstations.

FLEX-WP-0011 filed for the rest of the gap: flex-auth runs two production
Deployments on railiance01 but has never been brought under the
staged-promotion contract (RAIL-BS-WP-0006). No railiance/app.toml, no
stage commands, no canary or approval evidence; the deploy/ directory is
a rescue of specs that existed nowhere, not the sanctioned overlay shape.
Pre-existing debt found during the FLEX-WP-0010 rollout, not a regression
from it, and not a blocker for routine policy rollouts -- flex-auth fails
closed. T03 also flags that the coulombcore drain plan still lists
flex-auth on a host it no longer runs on.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-11 10:35:34 +02:00
9e6de5a50d Record production gap for FLEX-WP-0010 and re-probe FLEX-WP-0009
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
FLEX-WP-0010-T04: the deployed flex-auth-tenant-engine Deployment bakes
the policy package into its image, so production still serves the
four-action policy -- probed live, tenant.retire returns deny
unknown_action there while tenant.create allows. TEN-WP-0005-T05 is
unblocked in source but needs an image build from 8e127e5 and a rollout,
which this workplan does not scope. Stated in the workplan and in
examples/tenant-engine/README.md rather than left implied.

FLEX-WP-0009-T04: replayed all six user-engine fixtures against the
deployed flex-auth-user-engine service; all six matched expected effect
and reason, confirming the deployed failure matrix is still fail-closed.
T04 stays in progress -- the criterion also requires user-engine to
retire its local bridge, which is not flex-auth's to close.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 20:55:41 +02:00
8e127e50f7 Authorize tenant-engine lifecycle actions (FLEX-WP-0010)
Extend the tenant-engine write-API policy package with tenant.update,
tenant.retire, and tenant.reactivate, the three actions TEN-WP-0005
introduced. Until now every lifecycle mutation resolved to deny
unknown_action, blocking TEN-WP-0005-T05 production rollout.

- policy_package.md: three actions in valid_actions and frontmatter;
  CARING capabilities extended with EditAny/Archive/Restore
- protected_system_manifest.yaml, subject_manifest.yaml, and the rebuilt
  registry_snapshot.json carry all seven actions
- docs/tenant-engine-action-vocabulary.md documents the HTTP surfaces
- 8 new fixture pairs and 5 new Rego tests, including action-drift
  guards (tenant.retired, tenant_update -> unknown_action)

T02 decision, recorded in policy_package.md: tenant.retire does NOT get
stricter authorization yet. With one service subject and no assurance
claim in the CheckRequest there is nothing stricter to check, and a
condition the sole caller always satisfies would falsely read as
separate control. Retirement is reversible and non-destructive. Revisit
on KEY-WP-0005 assurance claims or a second operator subject.

Verified: 11/11 Rego tests, 16/16 fixtures, go test ./... green, gofmt
and go vet clean. End-to-end against a live serve with a real
tenant-engine through the unmodified FlexAuthWriteAuthorizer: update
6176c39c2f4d7b15, retire 8a801b8ee8455080, reactivate c64cf3713cecd970
all allow; unregistered actor denied unknown_subject
(59d3e99c6416be89, 403 write_denied).

Handoff revision for TEN-WP-0005-T05: package
tenant-engine.write-api.mutate v1 (ready, caring-0.4.0-rc2).

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 20:52:10 +02:00
8ba1755718 Plan tenant-engine lifecycle policy actions
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
TEN-WP-0005 added tenant.update / tenant.retire / tenant.reactivate to
tenant-engine's write API. FLEX-WP-0008's policy package predates them, so
every lifecycle mutation resolves to deny unknown_action -- correct
fail-closed, but it blocks TEN-WP-0005-T05 rollout and USER-WP-0021.

Requested by tenant-engine; action strings taken verbatim from the live
_RESOURCE_TYPES mapping.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-10 20:11:30 +02:00
ccf4b509be Deploy user-engine authorization policy
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
2026-08-09 02:21:29 +02:00
5217109103 Plan user-engine production authorization
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 1s
2026-08-09 01:57:18 +02:00
d2dc39a8b8 FLEX-WP-0008 T03-T04: tenant-engine live-lookup context adapter, close
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 3s
internal/adapters/tenantengine: HTTPClient.LiveRoles() calls tenant-engine's
GET /tenants/{id}/roles/live. LiveRolesResult.Available is the load-bearing
field -- false on any transport error, non-200, or malformed body, never
inferred as zero roles. AttachToContext() writes both tenant_roles and
tenant_roles_available into a CheckRequest.Context map; a consuming Rego
policy must check tenant_roles_available before trusting tenant_roles.

Architectural finding recorded in the workplan: engine.go's Check() has no
context-adapter hook, and none of the existing topaz/relationship/rule
adapters are wired into cmd/flex-auth either -- they're standalone packages
for downstream composition. This adapter is a request-preparation helper a
protected system's own request-building code calls before POST /v1/check,
not an engine-internal hook, matching that precedent exactly.

9 Go tests; gofmt/vet/build clean; go test ./... green repo-wide.

Verified as a real three-service chain: live flex-auth serve + live
tenant-engine, created a tenant and granted it a CUS role through the real
flex-auth-gated write path, then read it back through this adapter (via a
throwaway harness, not committed) -- known tenant: roles=[CUS]
available=true; unknown tenant: roles=[] available=false err="status 404".

FLEX-WP-0008 closed: T01-T04 all done. tenant-engine's write path is now
real end-to-end; any other protected system can pull live tenant capability
role context, fail-closed. Remaining open item unchanged from TEN-WP-0003:
KEY-WP-0005 (key-cape's IAM Profile core-claims gap).

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 23:33:34 +02:00
49de2f40ff FLEX-WP-0008 T01-T02: tenant-engine resource/action vocabulary + policy package
All checks were successful
CI Smoke / host-smoke (push) Successful in 0s
CI Smoke / container-smoke (push) Successful in 3s
docs/tenant-engine-{resource-namespace,action-vocabulary}.md: four actions
(tenant.create, tenant.role.grant, tenant.role.revoke, tenant.plan.assign)
matching tenant_engine/src/tenant_engine/authz.py's _RESOURCE_TYPES mapping
exactly. No resource_manifest.yaml -- tenant-engine's resources are created
dynamically, unlike ops-warden's fixed SSH-certificate inventory; documented
as a deliberate deviation.

examples/tenant-engine/: protected_system_manifest.yaml, subject_manifest.yaml
(one registered caller: tenant-engine's own service identity),
policy_package.md (Rego rules + embedded tests), policy_fixtures.yaml (8
allow/deny pairs), assembled registry_snapshot.json, two standalone
check_request examples, README.

Design decision made explicit in the workplan: operator/service-identity
authorization (one known subject, four known actions), not aal2+assurance +
tenant-capability-role checking -- CheckRequest carries no assurance claim
yet (TEN-WP-0003 already flagged actor as a plain request-body field, not a
real auth context), and a tenant's capability roles are the tenant's own
state, not a property of who may call tenant-engine's admin API. Revisit
once KEY-WP-0005 gives callers a real assurance-bearing identity.

Verified for real: built ./cmd/flex-auth, ran test-policy (6 tests + 8
fixtures, all pass), load-registry, check against both example requests.
Then ran a live flex-auth serve with this exact registry+policy and pointed
tenant-engine's real, unmodified FlexAuthCheckClient/FlexAuthWriteAuthorizer
at it over real HTTP: unknown subject -> 403, tenant-engine -> 201. go test
./... still green across the whole repo.

T03 (live-lookup context adapter for other protected systems) stays open --
new Go adapter package, tracked separately.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 23:05:57 +02:00
67b1f9161a Draft FLEX-WP-0008: tenant-engine consumer integration
All checks were successful
CI Smoke / host-smoke (push) Successful in 1s
CI Smoke / container-smoke (push) Successful in 5s
Registers tenant-engine as a flex-auth protected-system consumer in both
directions its boundary contract requires: tenant-engine's writes need
authorization (FlexAuthWriteAuthorizer in TEN-WP-0003 currently gets
deny/not_applicable for everything until a policy package exists), and
flex-auth's own decisions for other protected systems need tenant
capability roles as context input via a live-lookup adapter.

Scoped closer to FLEX-WP-0006/0007 (ops-warden's small security-lane
integration) than FLEX-WP-0003 (Markitect's CARING-benchmark integration)
-- tenant-engine's resource/action vocabulary is small.

Registered, not implemented.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-07-23 22:47:10 +02:00
339c35e876 Close ops-warden policy gate deployment 2026-06-30 00:52:56 +02:00
941501c590 FLEX-WP-0007: production registry fixture, tests, and sync runbook
Add production_registry_snapshot.json from ops-warden inventory with CI
coverage for real actors, IAM subject binding, ttl_out_of_bounds, and
unknown_actor_resource. Extend serve contract tests with /healthz and
publish the registry sync contract for operator deployment.
2026-06-24 14:52:35 +02:00
0fde95a87c FLEX-WP-0006: implement ops-warden signing gate policy 2026-06-23 21:17:42 +02:00
8a913d6163 Normalize agent instructions and workplan frontmatter (STATE-WP-0067)
- Align agent files with on-disk workplan prefixes (infer from workplan ids)
- Set workplan domain to registered domain_slug; add topic_slug where applicable
- Repair frontmatter delimiter formatting; migrate legacy task status literals
- Regenerate AGENTS.md, CLAUDE.md, and .claude/rules from State Hub templates
2026-06-22 23:16:25 +02:00
99a521e176 Document delegated mode operations 2026-05-17 07:27:45 +02:00
32933c71f9 Add directory group resolver adapters 2026-05-17 07:24:50 +02:00
360025e38b Add Keycloak authorization adapter path 2026-05-17 07:18:45 +02:00
ad4895187b Add rule PDP adapter boundary 2026-05-17 07:13:27 +02:00
4bb329c921 Add relationship PDP adapter boundary 2026-05-17 07:06:14 +02:00
1ce0181e8f Implement Topaz adapter 2026-05-17 06:58:04 +02:00
184ce5a380 Document Markitect integration flow 2026-05-17 06:41:07 +02:00
3d1967cb41 Add Markitect adapter contract tests 2026-05-17 06:36:52 +02:00
7e09a21c5f Add Markitect check fixtures 2026-05-17 06:32:05 +02:00
b6712850c3 Define Markitect action vocabulary 2026-05-17 06:26:13 +02:00
9e2591c1f4 Import Markitect resource manifests 2026-05-17 06:21:28 +02:00
12dbf52586 Mark core workplan completed 2026-05-17 06:16:13 +02:00
6586adb4f5 Define Markitect resource namespace 2026-05-17 06:14:04 +02:00
18054bd160 Add CARING examples and coverage 2026-05-17 06:05:18 +02:00
61e113f8b6 Add CLI and service skeleton 2026-05-17 05:59:48 +02:00
2b103ea70b Add local decision log 2026-05-17 05:51:37 +02:00
faea068721 Implement list allowed and explain 2026-05-17 05:45:36 +02:00
54984585e3 Implement deterministic check APIs 2026-05-17 05:38:57 +02:00
550d096cb2 Implement policy package loader 2026-05-17 05:30:40 +02:00
3c4f8fc2b4 Implement local registry store 2026-05-17 05:10:17 +02:00
7fdf6d63d5 Implement canonical schema foundation 2026-05-17 04:59:18 +02:00
dd0b9663c4 Refine workplans for CARING profile 2026-05-17 04:15:38 +02:00
f930e96568 IAM Profile consumption doc + claim fixtures; close FLEX-WP-0005
Completes FLEX-WP-0005 T05 and closes the Foundations and Topaz
Alignment workstream.

docs/iam-profile-consumption.md captures flex-auth's input surface
against NetKingdom IAM Profile v0.1:
- boundary (flex-auth consumes verified claims; upstream layer
  validates signatures and audiences)
- normalized input envelope (matches Markitect's EnterpriseIdentity)
- required, recommended, and tolerated claim variations
- role-claim location union (top-level / realm_access / resource_access)
- scope encoding (string vs array)
- principal-type detection (human / service / emergency)
- group-overage and freshness expectations
- production vs local-development handling

examples/claims/ ships five contract fixtures:
- key-cape-lightweight.yaml (profile minimum)
- keycloak-heavy.yaml (full variation set + MFA)
- service-account.yaml (svc-* hub-to-hub)
- emergency.yaml (break-glass with incident metadata)
- keycloak-group-overage.yaml (Entra-style hasgroups: true)

All fixtures parse as valid YAML. They become contract tests for the
standalone evaluator (FLEX-WP-0002 P2.4) and the Topaz adapter
(FLEX-WP-0004 T01); both code paths must produce identical normalized
envelopes for the same fixture.

FLEX-WP-0005 workstream marked status=done in this file and completed
in the State Hub. FLEX-WP-0002 is now fully unblocked.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
2026-05-16 09:09:36 +02:00