Skip to content

feat(dir): add manager-scoped agent discovery via pluggable org resolver#1469

Open
vivekkrishna wants to merge 2 commits into
agntcy:mainfrom
vivekkrishna:optional-org-chart-integration
Open

feat(dir): add manager-scoped agent discovery via pluggable org resolver#1469
vivekkrishna wants to merge 2 commits into
agntcy:mainfrom
vivekkrishna:optional-org-chart-integration

Conversation

@vivekkrishna
Copy link
Copy Markdown
Contributor

Summary

Closes #1445

Introduces manager-scoped agent discovery: given a manager alias, find all agent records owned by anyone in their org subtree. Ownership is expressed via the owner.id annotation on records; the org hierarchy is provided by a pluggable org.Resolver.

  • New --manager flag on the search command expands a manager alias to their full subtree (direct + indirect reports) and returns all records whose owner.id annotation matches any alias in that set
  • Pluggable org.Resolver interface (server/org/resolver.go) with a static YAML file backend as the first implementation
  • Optional by design — if org_resolver is absent from the config the server starts normally; --manager returns an informative error. All other search is unaffected.
  • RECORD_QUERY_TYPE_MANAGER = 16 added to proto (regenerated pb.go)
  • Dedicated SQL JOIN alias (owner_ann) for the owner filter, so --manager and --annotation can be combined without interference
  • E2e tests (13_manager_search_test.go) cover subtree expansion, leaf nodes, aliases outside the org chart, unknown aliases, and combined --manager + --annotation filtering

Configuration

server:
  org_resolver:
    type: "static"
    static:
      file: "org-chart.yaml"   # relative to config file directory, or absolute

Org chart format (YAML)

Usage

# Find all agents owned by alice or anyone in her org subtree
dirctl search --manager [email protected]

Design decisions — feedback welcome

  1. owner.id annotation convention: we rely on records being tagged with owner.id: <alias> to express ownership. This is a convention, not enforced by schema validation today. Should this be a first-class field, or is annotation-based ownership the right model?

  2. Proto enum vs server-side handling: RECORD_QUERY_TYPE_MANAGER is a new proto enum value. An alternative would be to handle --manager purely in the CLI by pre-expanding aliases before sending queries. The current approach keeps expansion server-side (where the org chart lives), which feels cleaner but does touch the wire format.

  3. Static-only resolver for now: the org.Resolver interface is designed to support LDAP, IdP, or Git-based team resolvers in the future, but only the static YAML backend is implemented here. Happy to drop the interface and ship a concrete type if the team prefers not merging an abstraction without a second implementation.

Test plan

  • go build ./... — server, CLI, e2e tests
  • go vet — server, CLI
  • All server unit tests pass
  • task gen — no uncommitted diffs after regeneration
  • task lint (golangci-lint via pre-commit hook) — passes
  • E2e annotation tests (12) — 10/10 pass (regression)
  • E2e manager tests (13) — 6/6 pass
  • E2e full suite — 190/191 pass (1 pre-existing failure in signature test unrelated to this change)

@vivekkrishna vivekkrishna requested a review from a team as a code owner May 6, 2026 14:27
@github-actions github-actions Bot added the size/M Denotes a PR that changes 200-999 lines label May 6, 2026
Introduces --manager flag on the search command that expands a manager
alias to their full org subtree (direct + indirect reports) and returns
all agent records whose owner.id annotation matches any alias in that
subtree.

Key changes:
- New pluggable org.Resolver interface with a static YAML file backend
- OrgResolverConfig added to server config; static resolver configured
  via org_resolver.type = "static" + org_resolver.static.file
- Relative file paths in config resolved against the config file's
  directory (via resolveRelativePaths in daemon/config.go)
- RECORD_QUERY_TYPE_MANAGER = 16 added to proto + regenerated pb.go
- OwnerAliases filter in RecordFilters uses a dedicated SQL JOIN alias
  (owner_ann) to avoid interference with --annotation filters
- SearchController uses functional options pattern (WithOrgResolver) so
  the resolver remains optional; --manager returns an error when no
  resolver is configured
- E2e tests (13_manager_search_test.go) verify subtree expansion, leaf
  nodes, unknown aliases, and combined manager+annotation filtering
- Test org chart wired into local testenv config

Signed-off-by: Vivek Krishna Choppa <[email protected]>
@vivekkrishna vivekkrishna force-pushed the optional-org-chart-integration branch from 021c121 to 6209972 Compare May 6, 2026 14:34
@ramizpolic
Copy link
Copy Markdown
Member

Hi @vivekkrishna, thank you for contributing. I do agree that ownership is something that needs to be addressed, but I am not sure if this is the approach we would want to take. There are two important things that I would like to adjust here:

  • Rather than doing ownership claims through annotations, we can patch OASF with dedicated fields to make it more explicit
  • Local discovery vs network discovery is not addressed here and only impacts local discovery

For this PR to go forward, I would suggest we start from an issue/discussion and agree on a plan collectively as this is an important feature. We do support right now ownership through DNS/HTTPs claims through record naming (e.g. my-agent vs https://microsoft.com/agents/my-agent/v1.0.0 but we have no way to aggregate these locally or on the network.

@vivekkrishna
Copy link
Copy Markdown
Contributor Author

Hi @ramizpolic , that makes sense, should we use this thread to discuss and finalize on the approach? #1468 ?

@ramizpolic
Copy link
Copy Markdown
Member

Yes, lets continue the discussion there. If you are available today (5th of May) at 5PM CEST, we have a public community meeting. This would be an interesting topic to discuss

@vivekkrishna
Copy link
Copy Markdown
Contributor Author

I can attend with a proposal, can you share the meeting link?

@ramizpolic
Copy link
Copy Markdown
Member

I can attend with a proposal, can you share the meeting link?

@vivekkrishna here is the google calendar link https://zoom-lfx.platform.linuxfoundation.org/meetings/agntcy?view=week

Implements single-source-of-truth ownership via OCI referrers:

- Proto: new agntcy.dir.ownership.v1.OwnershipClaim message + RECORD_QUERY_TYPE_OWNER=17 + CEL whitelist update
- API: OwnershipClaimReferrerType constant + MarshalReferrer/UnmarshalReferrer helpers
- DB: Owner table (record_cid, owner_id, claimed_at) auto-migrated; AddOwner/RemoveOwners methods; owners JOIN in handleFilterOptions
- Types: OwnershipDatabaseAPI interface; Owners filter field + WithOwners()
- Controller: enforces caller SPIFFE ID == owner_id when authn enabled; immediately indexes claim on push
- OCI: OwnershipClaimArtifactMediaType mapping
- Reconciler: new ownership task walks OwnershipClaimReferrerType referrers to keep DB in sync on restart
- CLI: dirctl ownership claim --record <CID> --owner <id>; dirctl search --owner flag
- E2E: 7 ownership-based search tests (exact, wildcard, combined filter, negative cases)

Part of agntcy#1468
@github-actions github-actions Bot added size/L Denotes a PR that changes 1000-1999 lines and removed size/M Denotes a PR that changes 200-999 lines labels May 9, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

kind/research Categorizes issue or PR as related to research activities. size/L Denotes a PR that changes 1000-1999 lines triage/community-review

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Epic] Agent Ownership & Org-Aware Governance

2 participants