Skip to content

Provision and mount role-specific service SVIDs before caller cutover - #16359

Merged
agentydragon merged 3 commits into
agentydragon:develfrom
agentydragon-agent:agent/service-svid-certificates
Nov 14, 2026
Merged

agentydragon merged 3 commits into
agentydragon:develfrom
agentydragon-agent:agent/service-svid-certificates

Conversation

@agentydragon-agent

@agentydragon-agent agentydragon-agent commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Issue Agentplane service certificates with client and server EKUs from the workload CA and mount them read-only with the trust bundle. Reuse the Sandbox Controller cert-manager/client mount pattern from #16324. Preserve current serving names/paths and the existing Gateway Runtime-control certificate; add separate Sessions, Runtime-proxy and Environments role credentials so the planned binary split moves identities rather than dividing one shared grant.

Stage 2 of #16342. Deliberately leaves out new service settings, receiver allowlists, caller switches and bearer/RBAC removal. Pinned images reject unknown settings; no new settings keys are rendered here. Mounting certificates does not activate new traffic. The system overview distinguishes these mounts from the planned binary split.

Validation: pre-commit and commit hooks passed. The red CI run was a stale test expectation: the Gateway serving workload certificate now intentionally has both client auth and server auth EKUs after becoming a service_certificate; no mount or manifest behavior failed. The repaired test checks those EKUs, all three role-specific client SVID URIs/usages, and each mounted Secret. bbr test //cluster/cdk8s/agentplane:test_runner_gateway_workload //cluster/cdk8s/agentplane:test_workload_trust //cluster/cdk8s/agentplane:test_sandbox_controller passed (invocation). The named changed Python libraries passed bbr build //cluster/cdk8s/agentplane:actions //cluster/cdk8s/agentplane:app //cluster/cdk8s/agentplane:central_sampler_workload //cluster/cdk8s/agentplane:egress //cluster/cdk8s/agentplane:history_service //cluster/cdk8s/agentplane:llm_ingress //cluster/cdk8s/agentplane:mcp_edge //cluster/cdk8s/agentplane:notifications //cluster/cdk8s/agentplane:policy_controller //cluster/cdk8s/agentplane:runner_gateway_workload //cluster/cdk8s/agentplane:workload_tls //agentplane/net/peertls:config (invocation). The earlier workload-trust, sandbox-controller, and manifest checks also passed (invocation); the existing manifest test’s generated patch artifact supplied the regenerated YAML. Flux, cert-manager and trust-manager objects have no deployment system test; staging is their first cluster. No service has begun using the new credentials.

Rollback: revert this PR before caller cutover. Confirm Flux becomes Ready, existing serving certificate Secrets remain mounted and current TLS clients still connect. After callers rely on these mounts, restore compatible caller settings/images before removing their Secrets/mounts; keep the workload CA and existing Runtime-control certificate intact.

Questions for Claude

None.

@github-actions

github-actions Bot commented Nov 14, 2026 •

Copy link
Copy Markdown
Contributor

Visual review for 655f016f

Request a manual rerun from the CI run page.

Warning

1 target used the latest devel baseline (d8258d69) because the PR base published none. Diffs there may include devel drift, not just this PR's changes.

No visual changes among the 1 affected Bazel test target. Open visual review.

@agentydragon-agent
agentydragon-agent force-pushed the agent/service-svid-certificates branch from de10bdf to 655f016 Compare November 14, 2026 06:51
@agentydragon
agentydragon merged commit 4c59ace into agentydragon:devel Nov 14, 2026
11 checks passed
agentydragon added a commit that referenced this pull request Nov 14, 2026
This is the single open batch PR for the Agentplane organization plan.
Further plan updates go here as commits until it merges, instead of one
PR each.

## Commit 1: re-pin to devel `1f3e26cc58` and place `environmentaccess`

Eight Agentplane commits landed after `02dc3c7a2e`: #16345, #16346,
#16340, #16350, #16352, #16342, #16347 and #16359. They added five Go
files and removed or moved none. None of them finishes a plan track.

- **New package `runner_gateway/environmentaccess`.** It holds the
environment rules from #16346.
- It moves with EnvironmentService to `environments/access` (package
`access`).
- It stays outside `internal/` because the open slice #16351 makes
Session admission enforce `bind_session` with it, so both binaries
import it.
- It is a rule parser over the shared policy reader, like `inboxaccess`
and egress `policy`.
- **New files in existing packages.** They take their package siblings'
dispositions:
  - `identity/auth/service{,_test}.go` is retained.
- `environments/environment_grants_test.go` moves with
EnvironmentService.
- **Landed steps recorded:**
- `transition-tolerance-removal`: #16340 dropped the pre-Identity
Dispatcher rows, and #16341 removes the branches. History's empty
Sandbox UID is no longer listed as "not a leftover": #16356 refuses
writers without one, ahead of the #16336 drop, which is on hold.
- `gateway-connection-lease-removal`: #16345 has merged and #16361 is
open.
- **Cut line, explicit resume.** Since #16346 an Identity with a
`resume` grant may resume, and every explicit resume reserves the
Dispatcher-database wake budget. After the split, EnvironmentService has
no database, so this crossing needs either its own bound or a call back
to Sessions. It is queued as an operator question, after the identity
fence.
- **Counts and freshness.** The ledger, counts, freshness evidence and
listing counts are updated: 1,275 files in 223 packages.

## Checks

- Structural check against the `1f3e26cc58` inventory: PASS (42 tracks,
1,275 files, 223 packages).
- `prettier@3.9.10 --check`: clean.
- Local Playwright: the home page and the report render at desktop and
mobile, in light and dark, with no horizontal overflow and no console
errors. The binaries section still shows all seven cut-line cards.
- No source behaviour tests run; this is a planning-only change.

---
_Generated by [Claude
Code](https://claude.ai/code/session_01AYUnw7BD5YA1NAuqjeKKSm)_

Co-authored-by: Claude <noreply@anthropic.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
Admit the exact `spiffe://agentplane/runtime-proxy` service role on
native Runtime control alongside the current Gateway role. Controller
passive WatchState remains Controller-only, and Sessions cannot
authenticate directly to Runtime. This supports moving the proxy
identity with Environments while Sessions calls the proxy over its own
network edge.

Deliberately leaves out caller switches, deployment settings, the binary
split, TokenReview removal and RBAC cleanup; receiver images must be
pinned first. The focused overview and Runtime SPEC describe the
optional edge.

Validation: pre-commit and commit hooks passed. `bbr test
//agentplane/env/runtime/control:control_test
//agentplane/env/runtime/internal/coordinator:coordinator_test` passed
(https://app.buildbuddy.io/invocation/39f3ddae-18d7-464b-8f1d-88e9162e41c6).
Real TLS tests exercise exact role denial and authenticated control.
Deployment suite `bbr test
//agentplane/system_tests/suites:test_dispatcher` passed in 237.8s
(https://app.buildbuddy.io/invocation/596bb764-f7c4-4ef0-bceb-1036a93d4adf).

Rollback: revert the receiver commit before any caller switch. After
cutover, restore compatible proxy caller images/settings first. Check
Runtime control, Session dispatch and Controller passive watches after
rollout.

Rebased onto `b9fe2e884a` and reconciled #16345’s Controller-bound
incarnation contract. The failed initial CI run had no build/test
invocation: trusted-fork context rejected a conflicted merge. After
rebase, `bbr test //agentplane/env/runtime/control:control_test
//agentplane/env/runtime/internal/coordinator:coordinator_test
//agentplane/system_tests/suites:test_dispatcher` passed
(https://app.buildbuddy.io/invocation/a1a0db6f-b038-4437-90bd-c6f4b6905fa2;
deployment suite236.3s). No new certificate-path or allowlist manifest
settings until #16359 merges and the receiver images are pinned.

## Questions for Claude

None.

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
Admit optional exact service SVIDs on the Notification Service's
existing read-only Session diagnostic methods. These callers can
read/watch diagnostic inboxes and subscriptions but cannot mutate
inboxes, send messages or become an agent Identity. Existing
ServiceAccount operator readers remain independently admitted during
overlap. The actual-TLS test exercises both credentials together and
denies unlisted roles and service mutations.

Stage 3 code/settings only. Deliberately leaves out caller switches,
manifest settings, TokenReview removal and RBAC changes. Certificate
issuance/mounts landed in #16359, but no new certificate paths or
allowlist keys may enter manifests until this receiver image is pinned.
System overview shows the optional diagnostic-reader edge.

Validation: scoped pre-commit passed including complete Gazelle drift.
Passed: `bbr test //agentplane/notification_service:unit_test
//agentplane/notification_service:integration_test
//agentplane/notification_service:test_settings
//agentplane/notification_service/internal/rpc:unit_test
//agentplane/notification_service/internal/rpc:integration_test
//cluster/cdk8s:test_generate_manifests`
(`c13e03cd-6942-43d2-b03f-cbc9866e22c2`). The two service integration
targets took 47.7s and 57.3s; the actual-TLS service reader cases ran in
the RPC integration target. The existing app/browser diagnostic facade
retains its current transport.

Rollback: revert this change and restore the previous receiver image
before service callers switch; confirm existing bearer diagnostic reads,
Notification health and delivery recover. No schema or deployment
changes are included.

## Questions for Claude

None.

---------

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
Add exact service SPIFFE allowlists to PolicyService’s separate
reader/writer capabilities and EgressAdmin’s read API. Both listeners
can verify client certificates using the configured trust bundle while
existing TokenReview callers keep working. The forward proxy’s workload
Identity boundary remains separate.

This is optional stage-3 receiver support. It deliberately leaves out
deployment settings, caller switches, TokenReview removal and RBAC
cleanup; code and receiver image pins come first. The overview diagram
records the optional certificate edges.

Validation: pre-commit and commit hooks passed. Isolated bbr
verification passed for
`//agentplane/egress/cmd:{listener_test,config_test}`,
`//agentplane/egress/internal/admin:admin_test`,
`//agentplane/policy_controller/internal/rpc:rpc_test`,
`//agentplane/policy_controller/cmd:config_test`, and both Python
`:settings` libraries
([invocation](https://app.buildbuddy.io/invocation/f06701c6-a146-460e-8c95-09362dad35fb)).
Deployment suite `bbr test
//agentplane/system_tests/suites/mcp:test_services` passed
([invocation](https://app.buildbuddy.io/invocation/b4f91053-f395-409d-82aa-311ab0db84af)).

Rollback: revert this receiver commit before enabling service callers;
after a caller cutover, restore compatible caller images/settings first.
Existing account admission remains available during this stage. Check
Policy watches/grants and Egress Admin health/decisions after rollout.
Flux, cert-manager and cluster policy objects have no system test and
are not changed here.

The generated-manifest CI failure was traced to newly serialized empty
service settings. Inactive defaults are now omitted. `bbr test
//agentplane/policy_controller:settings //agentplane/egress:settings
//cluster/cdk8s:test_generate_manifests` passed
(https://app.buildbuddy.io/invocation/b83a5f4b-ba45-4b72-963a-33056bef72b5).

Rollout gate: no new certificate-path or service-allowlist manifest
setting until #16359 merges and the receiver images are pinned.

Python authoring models now enforce the same exact service-ID and
client-trust requirements as Go. `bbr test
//agentplane/policy_controller:settings //agentplane/egress:settings
//cluster/cdk8s:test_generate_manifests` passed
(https://app.buildbuddy.io/invocation/8f4a7182-ce3e-416a-a5f2-4a36529a8b3d).

## Questions for Claude

None.

---------

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
Add optional exact service-SVID admission to the co-hosted Dispatcher,
EnvironmentService, Runtime proxy and Executor. Each receiver has its
own grants; Sessions, Environments and Runtime-proxy identities remain
movable with the planned binary split. Certificate actors retain
separate persisted provenance and wake budgets. Typed delegation uses
the effective Identity, never the actor's component grants. Preserve the
merged Identity explicit-resume rules and live UID/policy checks.

Stage 3 code and settings only. Deliberately leaves out caller switches,
deployment settings, binary extraction, TokenReview and RBAC removal.
#16359 has merged, but manifests must not set these keys or certificate
paths until these receiver images are pinned. Existing bearer callers
continue during the staged rollout; a certificate-bearing request cannot
fall back to bearer admission.

Validation: scoped pre-commit passed including complete Gazelle drift.
Passed: `bbr test //agentplane/runner_gateway:config_test
//agentplane/runner_gateway:test_settings
//agentplane/runner_gateway/environments/internal/management:unit_test
//agentplane/runner_gateway/internal/gateway:gateway_test
//agentplane/runner_gateway/dispatcher:store_integration_test
//agentplane/runner_gateway/migrations:test_migrations` (invocation
`9a6c13bb-c9c4-4b5c-b032-a58d46be4baa`). After integrating the new
Identity lifecycle contract and migration sequencing, `bbr test
//agentplane/runner_gateway/environments:environments_test
//agentplane/runner_gateway/environments/lifecycle:lifecycle_test
//agentplane/runner_gateway/migrations:upgrade_integration_test` passed
(`e05a4154-0a1a-4b50-804a-96e2f3e1682e`). Deployment tests all passed in
`30458d37-c117-4e09-bde2-0f9736b4b92d`:
`//agentplane/system_tests/suites:test_dispatcher` (278.6s),
`//agentplane/system_tests/suites/mcp:test_services` (341.1s),
`//agentplane/system_tests/suites/mcp:test_delegation` (200.8s), and
`//cluster/cdk8s:test_generate_manifests` (40.3s). Named
settings-library build also passed
(`82a1c289-c244-4d90-b7c2-a59a23e3768e`). System overview includes the
role boundaries.

CI found and corrected two integration gaps: ServiceAccount create
receipts now retain the existing `caller` encoding for old replicas and
orchestration readers, while service actors use independent attribution;
the Gateway method helper lives in the shared test fixture so the queue
test compiles. `bbr test
//agentplane/action_service/orchestration_v1:orchestration_v1_test
//agentplane/runner_gateway/environments/internal/management:unit_test
//agentplane/runner_gateway/environments:environments_test
//agentplane/system_tests/suites/mcp:test_actions` passed
(`a5051868-b8ce-4bcc-9ece-a8e762c55840`). The fresh-base
queue/Gateway/store check is running.

Rollback: revert the receiver change before any caller cutover, roll
back its image pin, and confirm existing bearer clients and Dispatcher
delivery recover. The new migration is additive; retain its
columns/table during rollback. After future service-attributed writes
begin, do not roll back without accounting for those rows, since old
receivers cannot use their new attribution. This PR enables no
production service callers.

## Questions for Claude

None.

---------

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
…16357)

Admit exactly configured service SVIDs on the sampler listener,
alongside existing bearer accounts. Persist service-owned Sessions using
the actual SPIFFE ID in a separate column; the authenticated service
never becomes a ServiceAccount UID and cannot reopen an account-owned
Session. The schema addition supports overlapping legacy writers.

Rebased PR head: `25619ca36759b7f2373fe0cb9a4a5155e06e3411`. This PR
targets devel because cross-fork native stacks are unsupported. It
reuses #16333’s optional TLS listener, adding client trust before any
manifest enables it.

Stage 3 only. This deliberately leaves out caller switches, production
settings, ownership transfer, outbound History/LLM authentication
changes and bearer/RBAC removal. In particular, stage 4 must explicitly
handle existing account-owned Sessions rather than map a service to an
account UID. The overview diagram records the optional service edge.

Validation: pre-commit and commit hooks passed. RPC and Session-store
tests passed in
[ca8830c5](https://app.buildbuddy.io/invocation/ca8830c5-457d-4d8a-a963-6c0de32a809c),
including exact service denial, mixed bearer rejection and separate
ownership. Isolated `bbr test` passed for
`//agentplane/central_sampler/internal/rpc:unit_test`,
`//agentplane/central_sampler/internal/sessionstore:sessionstore_test`,
`//agentplane/central_sampler/internal/settings:settings_test`, and
`//agentplane/central_sampler:settings`
([invocation](https://app.buildbuddy.io/invocation/2f7d4572-f56b-49a5-b15d-cccd004fa6ac)).
Deployment coverage is recorded below.

Rollback: before enabling service callers, revert this receiver commit;
leave the additive migration applied. Existing account-owned Sessions
remain readable by prior images. After service-owned Sessions exist, do
not revert to an old binary without a reviewed ownership cutover; the
migration down path refuses to orphan them. Check retained Sessions and
continuation after rollout.

Deployment suite `bbr test
//agentplane/system_tests/suites/mcp:test_services` passed
(https://app.buildbuddy.io/invocation/b49f4760-c385-4be6-85b7-236af088de77).

Rollout gate: no new certificate-path or service-allowlist manifest
setting until #16359 merges and the receiver images are pinned.

Inactive service defaults are omitted from rendered settings. `bbr test
//agentplane/central_sampler:settings
//cluster/cdk8s:test_generate_manifests` passed
(https://app.buildbuddy.io/invocation/d2ddfa23-2fcc-4176-8a44-45ad959f6d3a).

## Questions for Claude

Stage 4 needs an explicit ownership cutover for existing sampler
Sessions; no implicit service→ServiceAccount UID mapping is introduced.

---------

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
Allow explicitly configured service SVID readers on the Action Service’s
read methods, and a separately granted MCP service actor on typed
Connection delegation methods. Effective Identity bindings and live UID
checks remain the authorization authority. App service transport can
carry independently verified operator OIDC; a certificate alone never
grants operator access.

Rebased PR head: `d08a036087d904da1537801d9e677ad661364e93`. This PR
targets devel because native GitHub stacks do not support cross-fork
branches.

This is stage 3, disabled until allowlists are configured. It
deliberately leaves out caller changes, production settings, bearer
removal and RBAC cleanup; receiver images must be pinned first. The
overview includes the optional certificate/delegation edges.

Validation: pre-commit and commit hooks passed. Focused real-TLS
receiver/delegation/operator checks passed in invocation
[6f4579ed](https://app.buildbuddy.io/invocation/6f4579ed-156e-4107-b73c-b1e50c855871).
Final isolated `bbr` verification passed:
`//agentplane/action_service/cmd:config_test`,
`//agentplane/action_service/cmd:integration_test`,
`//agentplane/action_service/internal/rpc:integration_test`,
`//agentplane/action_service:settings`, and deployment suites
`//agentplane/system_tests/suites/mcp:test_actions` and
`//agentplane/system_tests/suites/mcp:test_delegation`
([invocation](https://app.buildbuddy.io/invocation/f1a3c082-baa2-4050-9e25-f54d292848a7)).

Rollback: revert the receiver commit before enabling service callers.
Existing bearer/OIDC/workload callers remain admitted. Once callers are
switched, first restore compatible caller images/settings before
reverting this receiver. Check Action watches, submissions and operator
decisions after rollout.

The generated-manifest CI failure was traced to newly serialized empty
settings. Empty service defaults are now omitted; `bbr test
//agentplane/action_service:test_settings
//agentplane/action_service:settings
//cluster/cdk8s:test_generate_manifests` passed
(https://app.buildbuddy.io/invocation/683fbe51-702d-4daa-b8fd-141f6e3bd6df).

Rollout gate: no new certificate-path or service-allowlist manifest
setting until #16359 merges and the receiver images are pinned.

## Questions for Claude

None.

---------

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
agentydragon pushed a commit that referenced this pull request Nov 14, 2026
…16358)

Add exact service SVID allowlists for LLM ModelConfig reads and Central
Sampler inference delegation. The sampler must supply a typed effective
Identity and Session envelope; live UID verification and the Identity’s
egress grants remain authoritative. A service certificate carries
neither a synthetic account nor Pod proof, and failed certificate
verification cannot select a bearer fallback.

Rebased PR head: `958c9417080866e425fa72e8195c479f0f4f28c3`. This PR
targets devel because cross-fork native stacks are unsupported.

Stage 3 only. Deliberately excludes production settings, the sampler’s
`auth.mode: agentplane_ingress` caller switch, other caller TLS changes,
and TokenReview/RBAC removal. Those wait for receiver image pins.
Staging’s existing bearer mode continues during this stage. The overview
includes optional service edges.

Validation: pre-commit and commit hooks passed. Isolated `bbr test
//agentplane/llm_ingress:ingress_test //agentplane/llm_ingress:settings`
passed (real TLS peer/delegation tests, exact caller denial, effective
Identity/Session, stale UID and bearer ambiguity). Deployment suite
coverage is recorded below.

Rollback: revert before enabling service callers; after caller
migration, first restore compatible caller images/settings. Existing
bearer/workload admission remains available at this stage. Check
ModelConfig discovery and ordinary inference after rollout.

Isolated `bbr test //agentplane/llm_ingress:ingress_test
//agentplane/llm_ingress:settings` passed
(https://app.buildbuddy.io/invocation/ff86e46a-7863-4843-a78a-19815e3c2aa1).
Deployment suite `bbr test
//agentplane/system_tests/suites/mcp:test_services` passed
(https://app.buildbuddy.io/invocation/16dc4905-93cc-4c45-bc49-9fb33e486584).

Rollout gate: no new certificate-path or service-allowlist manifest
setting until #16359 merges and the receiver images are pinned.

Inactive service defaults are omitted from rendered settings. `bbr test
//agentplane/llm_ingress:settings
//cluster/cdk8s:test_generate_manifests` passed
(https://app.buildbuddy.io/invocation/19584d67-2eb9-41cc-9e33-fbfdb3960e32).

## Questions for Claude

Before stage 4, verify staging central Sessions retain execution
Identity name and UID required by typed LLM delegation. No fallback to
bearer is permitted if that proof is absent.

Rebased after #16354 and #16357 merged; the only conflict was in
`system_overview.md`. Both merged diagrams and the LLM authentication
edge are preserved. Scoped pre-commit and `git diff --check` passed;
receiver code is unchanged by this rebase.

---------

Co-authored-by: agentydragon-agent <260791330+agentydragon-agent@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants