mirror of
https://github.com/mulgadc/spinifex.git
synced 2026-10-15 09:01:31 +00:00
docs: record EKS access entry owner extraction
This commit is contained in:
@@ -293,6 +293,7 @@ while the branch is in flight; they do not describe the umbrella repository's
|
||||
| `1cb868e68` | — | — | ECS task definition characterization before extraction (ADR-0003 S1, ADR-0004): stored keys and field names, every reference form and its not-found fault, repeatable deregister, an inactive revision still launching, bare-family launch resolution, a service pinning its resolved revision. Present contract and gaps, including the bare-family `iam:PassRole` re-resolution security gap, in `docs/package-boundary/ecs-task-definition-lifecycle.md`; no conformance claimed. |
|
||||
| `544b0c6a0` | `spinifex/handlers/ecs` (`TaskDefRecord`, `ContainerDef`, `TaskDefRevKey`, `TaskDefLatestRevKey`, `ParseTaskDefRef`, `TaskDefARN`, `TaskDefRefARN`, revision register/deregister/resolve/list) | `spinifex/domains/ecs/taskdefinition` (`Owner`, `Record`, `Container`, `PortMapping`, `SystemControl`, `ParseRef`, `ARN`, `RefARN`, keys) | ADR-0004 owner extraction (ADR-0003 S1 contract in `docs/package-boundary/ecs-task-definition-lifecycle.md`). Stored keys and JSON field names unchanged; the owner declares its own persisted `PortMapping`/`SystemControl` so it does not import `handlers/ecs/bus`. Launches use the launch-side `taskDefinitionResolver`; gateway authz and all `iam:PassRole` checks unchanged. `docs/service-interfaces.yaml` now lists `spinifex/handlers/ecs` and the new package under `spinifex_daemon`. Proves ownership and dependency direction only; no conformance claimed. |
|
||||
| `b36d70b22` | — | — | EKS access entry characterization before extraction (ADR-0003 S1, ADR-0004): persisted and nested field names, pre-existing JSON decodes, actions ignore cluster status, associate without an entry is not found, disassociating an unbound policy is a no-op, an empty update keeps username and groups, cluster delete sweeps only that cluster's entries, token review needs no cluster record. Present contract and gaps in `docs/package-boundary/eks-access-entry-lifecycle.md`; no conformance claimed. |
|
||||
| `68ee6f620` | `spinifex/handlers/eks` (`AccessEntryRecord`, `AssociatedAccessPolicy`, `AccessScope`, `AccessEntriesPrefix`, `AccessEntryKey`, `PrincipalARNHash`, access-entry KV helpers, policy catalogue, `effectiveGroups`, the access mutation logic) | `spinifex/domains/eks/access` (`Owner`, `Record`, `AssociatedPolicy`, `Scope`, `Spec`, `Get`, `List`, `Key`, `Prefix`, `PrincipalARNHash`, `SupportedPolicies`, `EffectiveGroups`) | ADR-0004 owner extraction (ADR-0003 S1 contract in `docs/package-boundary/eks-access-entry-lifecycle.md`). Stored keys and JSON field names unchanged; writes go only through `Owner`, including the creator-admin seed at cluster launch. The handler keeps AWS validation, the cluster existence check, error mapping and projection; gateway authz switches only its hash import. `docs/service-interfaces.yaml` now lists `spinifex/handlers/eks` and the new package under `spinifex_daemon`. Proves ownership and dependency direction only; no conformance claimed. |
|
||||
|
||||
The EC2 contract row is intentionally different from the directory moves: it creates
|
||||
a compatibility boundary. `ec2.cmd.*` retains its deployed one-token NATS
|
||||
@@ -392,6 +393,7 @@ These residuals were recorded by individual slices and must be resolved once the
|
||||
- `handlers/rds` → `domains/rds/subnetgroup` (legacy edges): `instanceReferences` binds `Dependants` by scanning instance records, and `tags.go` writes the group record through its generic tag registry. The first clears when the RDS instance gains its own owner and answers `Dependants` from it. The second clears when tagging invokes a subnet-group-owned tag/untag capability rather than writing the record; moving the tagging adapter to `domains/rds/awsapi` alone does not clear it.
|
||||
- `handlers/ecs` → `domains/ecs/taskdefinition` (legacy edges): `tags.go` reads and writes the revision record through its generic tag registry; this clears when ECS tagging invokes an owner-provided tag mutation capability, and moving `tags.go` to `domains/ecs/awsapi` alone does not clear it. `taskDefinitionResolver` returns the persisted `Record` to task and service launch code; when the task and service owners are extracted, replace the record crossing that boundary with a consumer-owned resolved task-definition (launch-spec) projection. Moving packages has not made the record private.
|
||||
- `domains/ecs/taskdefinition` (deliberate duplication, not debt): private `getJSON`, `putJSON` and `keysWithPrefix` copy the raw-KV helpers in `handlers/ecs` so the extraction keeps ECS's get/put/list error and recovery semantics. Revisit only if a later, tested state abstraction proves it preserves those semantics; do not migrate ECS to `kvstore` merely to remove them.
|
||||
- `handlers/eks` → `domains/eks/access` (legacy edges): `ResolveTokenReview` opens the EKS bucket in the gateway process and reads records through the exported `access.Get`; this clears when token review asks the owner across a contract rather than opening the bucket itself. `DeleteClusterPrefix` erases access-entry keys as part of its blanket cluster sweep; this clears when cluster delete invokes an owner-provided removal of the cluster's entries. The owner returns the persisted `Record` to the AWS adapter and token review; replace it with consumer-owned projections when those consumers are extracted.
|
||||
- `docs/service-interfaces.yaml` (coverage gap): no `ecs.*` subjects are listed and the manifest lint does not cover them, so ECS publisher/subscriber edges play no part in suite selection. Add them only after tracing the actual publishers and subscribers.
|
||||
- Merge-time follow-up in the umbrella repository: the `Makefile` `invariants-check` target, the `docs-pr.yml` clause cross-check, `.claude/hooks/architecture-traps.sh` and a `check-invariants.sh` comment hard-code `spinifex/spinifex/network/invariants`. They must change with the pointer bump that brings in this branch, or the docs-pr cross-check silently skips. Live specs and proposals citing `spinifex/network/` will report unresolved citations until updated.
|
||||
|
||||
|
||||
@@ -1,7 +1,8 @@
|
||||
# EKS access entry: lifecycle contract
|
||||
|
||||
Present contract under ADR-0003 S1, recorded before the resource moves.
|
||||
Present contract under ADR-0003 S1, recorded before the resource moved and updated after the owner extraction.
|
||||
It describes the code as it stands, so it claims no conformance; the gaps below are observed behaviour, not targets.
|
||||
The extraction establishes resource ownership and dependency direction only; it adds no ADR-0003 evidence for interruption, recovery, fencing or readiness.
|
||||
Paths are relative to `spinifex/` unless they start with `tests/`.
|
||||
|
||||
## Scope
|
||||
@@ -13,9 +14,10 @@ Create, update, delete and policy association complete synchronously within the
|
||||
|
||||
| Item | Present behaviour | Evidence |
|
||||
|---|---|---|
|
||||
| Identity | Cluster name plus principal ARN. Key and ARN suffix use `sha256hex(principalARN)` (`handlers/eks/store.go` `PrincipalARNHash`). ARN `arn:aws:eks:{region}:{account}:access-entry/{cluster}/{hash}` (`foundation/aws/arn/eks.go`); the AWS ARN shape differs and is not verified. | `handlers/eks/service_impl_test.go` `TestAccessEntry_CreateDescribeListDelete`, `handlers/eks/store_test.go`, `gateway/eks/authz_test.go` `TestResourceARNsAccessEntryMatchesHandler` |
|
||||
| Identity | Cluster name plus principal ARN. Key and ARN suffix use `sha256hex(principalARN)` (`domains/eks/access/store.go` `PrincipalARNHash`). ARN `arn:aws:eks:{region}:{account}:access-entry/{cluster}/{hash}` (`foundation/aws/arn/eks.go`); the AWS ARN shape differs and is not verified. | `handlers/eks/service_impl_test.go` `TestAccessEntry_CreateDescribeListDelete`, `domains/eks/access/store_test.go` `TestKeyPaths`, `gateway/eks/authz_test.go` `TestResourceARNsAccessEntryMatchesHandler` |
|
||||
| Scope | Account and Region, within one cluster: keys live under `clusters/{cluster}/access-entries/` in the `eks-account-{account}` bucket. | `handlers/eks/access_lifecycle_test.go` `TestAccessEntryPersistedLayout_TopLevelAndNestedFieldNames`, `TestAccessEntryRecord_DecodesHandWrittenJSON`, `handlers/eks/create_cluster_test.go` `TestCreateCluster_SeedsCreatorAdminAccessEntry` |
|
||||
| Durable owner and record | `handlers/eks/access_entry.go` writes `AccessEntryRecord` with nested `AssociatedAccessPolicy` and `AccessScope` (`handlers/eks/types.go`). The cluster launch also writes the creator-admin entry, and `DeleteClusterPrefix` (`handlers/eks/cluster_state.go`) erases entries with the cluster. The gateway process reads records directly through `ResolveTokenReview` (`handlers/eks/token_review.go`). | `handlers/eks/access_lifecycle_test.go` `TestAccessEntryPersistedLayout_TopLevelAndNestedFieldNames`, `TestAccessEntryRecord_DecodesHandWrittenJSON`, `handlers/eks/create_cluster_test.go` `TestCreateCluster_SeedsCreatorAdminAccessEntry` |
|
||||
| Durable owner and record | `domains/eks/access` (`Owner`) is the only writer of `Record` with nested `AssociatedPolicy` and `Scope`: Create, SeedCreatorAdmin (cluster launch), Update, Associate, Disassociate and Delete. Keys and field names are unchanged by the move. `DeleteClusterPrefix` (`handlers/eks/cluster_state.go`) still erases entries with the cluster, and the gateway process reads records through the exported `access.Get` in `ResolveTokenReview` (`handlers/eks/token_review.go`). | `handlers/eks/access_lifecycle_test.go` `TestAccessEntryPersistedLayout_TopLevelAndNestedFieldNames`, `TestAccessEntryRecord_DecodesHandWrittenJSON`, `domains/eks/access/owner_test.go`, `domains/eks/access/store_test.go`, `handlers/eks/create_cluster_test.go` `TestCreateCluster_SeedsCreatorAdminAccessEntry` |
|
||||
| AWS adapter | `handlers/eks` keeps request validation (entry type, supported policy, scope), the cluster existence check (`acctKVForCluster`), awserrors mapping and the AWS projection. `gateway/eks/authz.go` uses `access.PrincipalARNHash`. | `handlers/eks/service_impl_test.go` access cases, `gateway/eks/authz_test.go` `TestResourceARNsAccessEntryMatchesHandler` |
|
||||
| Desired state | Principal, Kubernetes username and groups, type (`STANDARD` only), tags (set at create only) and cluster-scoped access policy associations. | `handlers/eks/service_impl_test.go` `TestAccessEntry_RejectsNodeType`, `TestAccessPolicy_AssociateRejectsUnsupportedPolicyAndScope`, `TestAccessPolicy_AssociateRejectsNamespaceScope`, `handlers/eks/access_lifecycle_test.go` `TestAccessEntry_UpdateWithNoFieldsKeepsUsernameAndGroups` |
|
||||
| Generation | None. Update, associate and disassociate retry against the KV revision; create and delete do not. | |
|
||||
| Observed state | Not tracked; the record is the only state. | |
|
||||
@@ -34,6 +36,7 @@ Create, update, delete and policy association complete synchronously within the
|
||||
3. Access actions do not check cluster status (see dependencies row), and opening the bucket creates it for an account that has none.
|
||||
4. Entries can outlive their cluster (interrupted prefix purge) or carry over to a recreated cluster (reclaim and failed launch keep the meta and do not purge entries separately).
|
||||
5. Token review authenticates against an entry without checking the cluster exists or its status.
|
||||
6. `ResolveTokenReview` opens the EKS bucket and reads the record in the gateway process, outside the owner.
|
||||
6. `ResolveTokenReview` opens the EKS bucket and reads the record in the gateway process through the exported `access.Get`, outside the owner.
|
||||
7. List ignores `maxResults` and `nextToken`; tagging an access-entry ARN returns `NotImplemented`.
|
||||
8. No ADR-0003 S5 failure or recovery evidence.
|
||||
9. Handler code receives the persisted `Record` from the owner, so the storage shape still crosses into the AWS adapter and token review. It is a temporary extraction boundary, not the narrow projection ADR-0004 asks for.
|
||||
|
||||
Reference in New Issue
Block a user