Repository navigation
feat(workcontext): WorkScopeV1 selects a resource owner; containment fails closed without it - #845
Merged
Conversation
…fails closed without it WorkScopeV1 gains resource_owner_id (field 4): the scope covers only the resources that principal owns (an installed solution's principal); with resource_ids, both must match. ScopeContained treats the owner as a narrowing: a parent row naming an owner covers only a child naming the same owner, so a child may add an owner but never drop or change one, and an ask naming no owner is never covered by an owner-selected row, so owner-blind checks fail closed. Runnable operations never declare an owner. Go and Python bindings regenerated with codefly generate proto. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
antoinetoussaint-byte
added a commit
that referenced
this pull request
Oct 26, 2026
fix(workcontext): owner scope follow-ups from review r109 of #845
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.
What we are trying to do
An installed solution becomes a principal of its organization (the solution-principal model, specified in codefly-dev/authority#11). Its roles grant scopes on the data that principal owns, not on the whole kind and not as lists of ids. A capability therefore needs an owner selector, and every reader must fail closed when it cannot compare owners. This is step 1 of the implementation; the authority and the readers depend on it.
The change
WorkScopeV1.resource_owner_id = 4(proto/codefly/base/v0/work_context.proto).resource_ids, a resource is covered only when both match.buf.validate: at most 512 bytes, no whitespace, no NUL, no*.codefly generate proto(--localfor Go,--template buf.gen.python.yamlfor Python).workcontext.ScopeContainedis owner-aware. A parent row naming an owner covers only a child naming that same owner. So:ScopeContainedfails closed instead of reading the scope as the whole kind. That includes the authority client'sClaims.Allows.Child) and verify (chain attenuation) use this rule unchanged, so signing and verifying carry the owner as part of the scope.runnable/operation.go). The authority selects the owner per installation; a declared one is refused by name.docs/work-context.mddescribes the scope shape and the owner rule.There is deliberately no
Claims.AllowsOwnedin core. Core has noClaims; the owner-aware reader question (AllowsOwned,allows_owned,allowsOwned) belongs to the authority client libraries in codefly-dev/authority, built on thisScopeContained.Reuse
The rule is an added condition in the existing per-row loop of
ScopeContained(oneif), so every caller inherits it: mint, verify, the runnable admission and the readers. No second containment function.Classification
This is a fix at the owner: the scope schema and the one attenuation rule.
Tests
workcontext/owner_test.go:ErrInvalid;*, 513 bytes) never mint.runnable/operation_test.go: a declared resource owner is refused ("never declared").make buf-lintis clean, andmake buf-breakingreports "no breaking change against origin/main".resource_owner_id.go vet ./...is clean.go test ./...passes in every package (no FAIL).go test -racepasses inworkcontext/...,runnable/...,policy/...andsolutionhost/....Not run: the
sandbox_e2e,nix_requiredtagged suite andproto_companion_requiredtests (they touch neither surface).🤖 Generated with Claude Code