fix(vender): refuse agent credentials for resources outside the caller organisation - #166
Merged
Merged
Conversation
…r organisation The worker forwards the organisation carried on its dispatch payload to the credential vender and refuses to request credentials without one. The vender now requires that organisation, resolves the owning organisation of the agent and of every declared datastore and integration, and rejects the whole request before any role is created or assumed when an id belongs to another organisation or cannot be resolved. The policy manager refuses to add an agent principal to a datastore or integration role trust policy, so the boundary that previously held only by construction is now enforced and pinned by test. The vender Lambda gains read access to the agent-config, datastores and integrations tables.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The agent credential vender turned an agent's declared datastore and integration ids into
sts:AssumeRolegrants without checking which organisation those resources belong to, and the worker never told it which organisation the task ran for. The only thing preventing cross-organisation access was incidental: datastore and integration roles happen to trust only Lambda execution roles, and nothing enforced that.This change makes the vender organisation-aware and turns the incidental boundary into a designed one:
additionalTrustedPrincipals. Because these roles are created at runtime rather than in CDK, the regression is a policy-manager unit test rather than a template assertion.Testing
Run with the CI job commands:
backend/:SPLIT_GATES_ENV=test npm test -- --ci --coverage— 521 suites, 7964 tests, 0 failures attributable to this change (one pre-existing intermittent test in an unrelated dead-code guard passes on rerun and in isolation)npx tsc --noEmit -p backend— cleanpython3 -m pytest arbiter/workerWrapper/__tests__ -qfrom the repo root — 399 passed, 3 skippednpm run split:gates— all rails pass;cdk synth --all— successNew coverage: vender rejects a missing organisation, an agent whose organisation differs, a datastore or integration in another organisation, and an unresolvable id, each asserted to occur before any role creation or assumption; same-organisation requests succeed; worker forwards the organisation and refuses without it; policy manager rejects agent principals for datastore and integration role scopes.
Not verified here
The new cross-stack table references and the live table lookups can only be confirmed against a deployment.
Operational note
Datastore rows whose organisation was recorded as the literal selector label
All Organizations(a previously fixed create-path defect) will now be rejected by the vender for any agent that declares them. That is the intended fail-closed behaviour, but it means agents bound to those datastores lose scoped credentials until the rows are corrected — the pending backfill becomes functional rather than cosmetic.