Skip to content

Add MCP proxy Agent Identity#1265

Open
jhivandb wants to merge 14 commits into
wso2:mainfrom
jhivandb:task/mcp-proxy-agent-identity
Open

Add MCP proxy Agent Identity#1265
jhivandb wants to merge 14 commits into
wso2:mainfrom
jhivandb:task/mcp-proxy-agent-identity

Conversation

@jhivandb

@jhivandb jhivandb commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Purpose

Adds the Agent Identity security foundation for MCP proxies: an org-global scope catalog and the per-environment tool→scope binding model that the gateway mcp-auth/mcp-authz policies and env-Thunder grant management will build on.

This PR covers Phase 0 (preconditions) and Phase 1 (backend scope catalog) only. Console UI (Phase 2) and E2E (Phase 3) are tracked separately and are not in this PR.

Goals

  • Give an organization a resource-agnostic, org-global catalog of scope names.
  • Store per-environment MCP tool→scope bindings on the proxy config (grants themselves live in each environment's Thunder instance, not in AMS).
  • Enforce scope-catalog access with dedicated RBAC permissions.
  • Record the verified env-Thunder grant model that later phases (gateway policy emission, direct Thunder passthrough) depend on.

Approach

  • Migration 029_create_scopes — new scopes table (org_name, name, description, timestamps) with a (org_name, name) uniqueness constraint and an org index.
  • Model + repositorymodels.Scope and ScopeRepository (List/GetByName/Create/Update/Delete) with a moq-generated mock.
  • Spec-first APIdocs/api_v1_openapi.yaml adds GET/POST /orgs/{orgName}/scopes and PUT/DELETE /orgs/{orgName}/scopes/{scopeName}; spec/ regenerated via make spec.
  • ServiceScopeService validates the scope-name grammar ^[A-Za-z0-9:._\-]{1,256}$, rejects duplicates (ErrConflict), and blocks deletion while any MCP proxy environment tool binding references the scope (paginated catalog scan).
  • Controller + routes — thin handlers mapping sentinel errors to HTTP; each route declares its own permission via HandleFuncWithValidationAndAuthz.
  • RBAC — new scope:create/read/update/delete permissions, granted to Admin/AI Lead (full) and Developer/Platform Engineer (read).
  • Model groundworkMCPToolScopeBinding and ToolScopeBindings fields added to the MCP proxy config (flat + per-environment), consumed by the delete-guard binding scan.
  • Docs — spec, plan, preflight anchors, and live env-Thunder grant-model verification results committed under docs/superpowers/.

User stories

As an org admin/AI lead, I can define and manage a catalog of scopes for my organization so that (in later phases) MCP proxy tools can be bound to scopes and enforced per environment.

Release note

Add an org-global scope catalog API for MCP proxy Agent Identity security (backend foundation).

Documentation

N/A — backend foundation only; user-facing documentation will accompany the console (Phase 2) work.

Training

N/A — no training-content impact.

Certification

N/A — no impact on certification exams.

Marketing

N/A — foundational backend change, not independently promoted.

Automation tests

  • Unit tests

    services/scope_service_unit_test.go covers name validation, duplicate rejection, delete-blocked-while-bound, delete-unbound success, and missing-scope-not-found. make test-unit passes (all packages ok).

  • Integration tests

    None added in this PR; repository/controller integration coverage arrives with the console and E2E phases.

Security checks

Samples

N/A.

Related PRs

Builds on the merged MCP proxy UX revamp (PR #1258). Follow-up PRs will add gateway mcp-auth/mcp-authz emission, env-Thunder scope resource-server + grant passthrough, and the console UI.

Migrations (if applicable)

Adds migration 029_create_scopes. Run make dev-migrate (or the standard migration path) before starting the service. Tested against the local PostgreSQL dev database.

Test environment

  • Go 1.25.x, macOS (darwin/arm64)
  • PostgreSQL (local dev DB) for the migration

Learning

Spiked the env-Thunder grant model against a live environment to confirm the resource-server / role / group grant shapes and that agents must request scopes in the token request (Thunder filters to entitlements). Findings recorded under docs/superpowers/specs/.

Summary by CodeRabbit

  • New Features

    • Added org-level scope management, including listing, creating, updating, and deleting scopes.
    • Added environment-level agent identity management for groups, roles, members, assignees, and agent picker listings.
    • Added support for identity-based MCP environment configuration with per-tool scope bindings.
  • Bug Fixes

    • Preserving existing names and permissions is now more reliable when updating groups and roles.
    • Scope deletion now blocks when the scope is still in use.

@coderabbitai

coderabbitai Bot commented Jul 7, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

This PR introduces an org-global scope catalog and env-scoped agent identity management on top of Thunder. It adds scope CRUD APIs and storage, agent identity group/role/assignment/agent-picker endpoints, Thunder client extensions for member/scope operations, MCP proxy identity-security validation and policy emission, generated OpenAPI/client artifacts, RBAC permissions, a DB migration, dependency wiring, and deployment/e2e scope updates.

Changes

Backend Agent-Identity Security Feature

Layer / File(s) Summary
Thunder identity client and helpers
agent-manager-service/clients/thundersvc/{identity_client.go,identity_client_test.go,identity_merge.go,identity_merge_test.go,identity_types.go,env_resolver.go,client.go}, agent-manager-service/clients/clientmocks/{env_identity_client_mock.go,env_thunder_resolver_fake.go}, agent-manager-service/controllers/identity_controller.go
Adds typed group member operations, EnsureScopeResourceServer, ResolveIdentity/EnvIdentityClient, full-replace role/group merge helpers, mocks, and tests.
Scope catalog storage and service
agent-manager-service/models/scope.go, db_migrations/031_create_scopes.go, db_migrations/migration_list.go, repositories/scope_repository.go, repositories/repomocks/scope_repository_mock.go, services/scope_service.go, services/scope_service_unit_test.go, utils/errors.go
Adds the Scope model, migration, repository, service with name validation, conflict/deletion binding checks, and unit tests.
Scope API and RBAC
controllers/scope_controller.go, api/scope_routes.go, api/app.go, rbac/permissions.go, rbac/predefined_roles.go, utils/constants.go
Adds scope CRUD handlers, route registration, and Scope*/AgentIdentity* RBAC permission grants.
Agent identity passthrough API
controllers/agent_identity_controller.go, controllers/agent_identity_controller_unit_test.go, api/agent_identity_routes.go, repositories/agent_thunder_client_repository.go, repositories/repomocks/agent_thunder_client_repository_mock.go
Adds group/role/assignment/agents-picker HTTP handlers, route wiring, binding lookup, and unit tests.
MCP proxy identity security
models/llm_provider.go, models/mcp_proxy.go, services/mcp_proxy_service.go, services/mcp_proxy_service_unit_test.go, services/mcp_proxy_deployment.go, services/mcp_proxy_deployment_test.go
Adds identity security/tool-scope-binding models, validation, storage, and identity auth policy emission with tests.
OpenAPI spec and generated clients
docs/api_v1_openapi.yaml, spec/api_agent_identity.go, spec/api_scopes.go, spec/client.go, spec/model_*.go
Adds scope/agent-identity OpenAPI paths and generated Go client/model types.
Dependency wiring
wiring/params.go, wiring/wire.go, wiring/wire_gen.go
Wires scope and agent-identity repositories/services/controllers into DI.
Deployment scope configuration
console/apps/web-ui/public/config.js, deployments/docker-compose.yml, deployments/helm-charts/.../values.yaml, deployments/helm-charts/.../amp-thunder-bootstrap.yaml, deployments/setup/register-amp-resources.sh, test/e2e/framework/auth.go
Updates OAuth scope allowlists and Thunder bootstrap resource/action registrations.

Estimated code review effort: 5 (Critical) | ~120 minutes

Sequence Diagram(s)

sequenceDiagram
  participant Client
  participant AgentIdentityController
  participant EnvThunderResolver
  participant EnvIdentityClient
  participant ScopeRepository

  Client->>AgentIdentityController: CreateRole(name, scopes)
  AgentIdentityController->>ScopeRepository: validateScopesInCatalog(scopes)
  ScopeRepository-->>AgentIdentityController: catalog scopes
  AgentIdentityController->>EnvThunderResolver: ResolveIdentity(org, env)
  EnvThunderResolver-->>AgentIdentityController: EnvIdentityClient
  AgentIdentityController->>EnvIdentityClient: EnsureScopeResourceServer(scopes)
  EnvIdentityClient-->>AgentIdentityController: resourceServerID
  AgentIdentityController->>EnvIdentityClient: CreateRole + AddRolePermissions
  EnvIdentityClient-->>AgentIdentityController: role created
  AgentIdentityController-->>Client: 201 Created
Loading
sequenceDiagram
  participant Client
  participant MCPProxyService
  participant ScopeRepository
  participant GatewayRepository

  Client->>MCPProxyService: Create/Update(proxyConfig)
  MCPProxyService->>MCPProxyService: validateMCPEnvironments(env)
  MCPProxyService->>ScopeRepository: load org scope catalog
  ScopeRepository-->>MCPProxyService: known scopes
  MCPProxyService->>GatewayRepository: resolve active gateway
  GatewayRepository-->>MCPProxyService: gateway manifest or none
  MCPProxyService->>MCPProxyService: gatewayHasMCPIdentityPolicies(mcp-auth, mcp-authz)
  MCPProxyService-->>Client: validation result / persisted config
Loading

Possibly related PRs

  • wso2/agent-manager#1251: Both PRs modify the environment Thunder resolver/client layer, adding ResolveIdentity/EnvIdentityClient alongside AgentID provisioning in clients/thundersvc.
  • wso2/agent-manager#1258: Main PR's MCP proxy identity-mode ToolScopeBindings and policy emission build on the retrieved PR's per-environment MCPEnvironmentConfig/deployment refactor.
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise and reflects the main Agent Identity addition, though it is broader than the scope-catalog work.
Description check ✅ Passed All required sections are present and mostly complete, with relevant implementation, testing, and migration details.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@jhivandb jhivandb force-pushed the task/mcp-proxy-agent-identity branch from e18a4cc to b95c2ab Compare July 7, 2026 13:22
@jhivandb jhivandb changed the title Add org-global scope catalog API for MCP proxy Agent Identity [Draft] Add org-global scope catalog API for MCP proxy Agent Identity Jul 7, 2026
@jhivandb jhivandb changed the title [Draft] Add org-global scope catalog API for MCP proxy Agent Identity [Draft] Add MCP proxy Agent Identity Jul 7, 2026
@jhivandb jhivandb marked this pull request as ready for review July 7, 2026 20:08

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 6

🧹 Nitpick comments (4)
agent-manager-service/docs/api_v1_openapi.yaml (1)

9548-10095: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚖️ Poor tradeoff

Generic object schemas for Thunder passthrough responses reduce client type safety.

Most agent-identity group/role/member/assignment responses use an untyped type: object schema instead of a concrete schema, unlike the rest of the API surface. This appears to be an intentional passthrough design (per the linked design doc), so I'm not flagging it as a defect, but consider adding at least minimal typed schemas for the more commonly consumed responses (e.g., group/role list/detail) in a follow-up once the Thunder response shapes stabilize, to improve generated console/client type safety.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agent-manager-service/docs/api_v1_openapi.yaml` around lines 9548 - 10095,
The agent-identity Thunder passthrough responses are still modeled as generic
object types, which limits generated client/console type safety. Add minimally
typed response schemas for the commonly used group and role list/detail
endpoints in the OpenAPI spec, and wire them into the relevant operations such
as listAgentIdentityGroups, getAgentIdentityGroup, listAgentIdentityRoles, and
getAgentIdentityRole. Keep the passthrough design intact where needed, but
replace the broad object responses with concrete schemas wherever the Thunder
shape is stable enough.
console/apps/web-ui/public/config.js (1)

27-32: 📐 Maintainability & Code Quality | 🔵 Trivial

Scope allowlist duplicated across 4+ config surfaces.

This scope string is now duplicated verbatim in config.js, both docker-compose.yml service blocks, and both values.yaml keys (plus a differently-formatted copy in test/e2e/framework/auth.go). Every future scope addition/removal must be replicated correctly everywhere, or environments will silently diverge in RBAC coverage.

Consider generating this list from a single source of truth (e.g., derive from rbac/permissions.go at build/deploy time) rather than hand-maintaining N copies.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@console/apps/web-ui/public/config.js` around lines 27 - 32, The scope
allowlist is duplicated in the config and will drift across environments, so
replace the hand-maintained string in the scopes configuration with a single
source of truth generated from the canonical permissions definition. Update the
logic around the scopes field in config.js to derive the list from
rbac/permissions.go (or an equivalent shared generator) so docker, Helm, and
test configs consume the same emitted set instead of separately copied scope
strings.
agent-manager-service/services/scope_service_unit_test.go (1)

32-100: 📐 Maintainability & Code Quality | 🔵 Trivial | ⚡ Quick win

Missing coverage for Create conflict/success and Update paths.

Existing tests cover name validation and Delete, but Create's duplicate-conflict branch (Lines 75-76 in scope_service.go) and Update (success/not-found) are untested. Given the TOCTOU concern flagged in scope_service.go, a test asserting Create returns utils.ErrConflict for an existing name would help lock in the intended behavior.

As per path instructions: "Write service unit tests in services/<service>_unit_test.go... assert the service's own logic with assert.ErrorIs / assert.NotErrorIs for sentinels."

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agent-manager-service/services/scope_service_unit_test.go` around lines 32 -
100, Add unit coverage in ScopeService tests for the missing Create
duplicate-conflict path and the Update flow. In the ScopeService.Create test
cases, mock ScopeRepositoryMock.GetByName to return an existing scope and assert
the result is utils.ErrConflict; also add a successful Create case that verifies
the repository write path is reached. Add ScopeService.Update tests for both a
successful update and the not-found branch by mocking ScopeRepositoryMock
accordingly, and use assert.ErrorIs/assert.NoError to validate the service’s own
sentinel behavior.

Source: Path instructions

agent-manager-service/db_migrations/029_create_scopes.go (1)

36-38: 🚀 Performance & Scalability | 🔵 Trivial | 💤 Low value

Redundant index on org_name.

The uq_scopes_org_name unique constraint on (org_name, name) already backs an index whose leading column is org_name, so idx_scopes_org is likely redundant and only adds write overhead.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agent-manager-service/db_migrations/029_create_scopes.go` around lines 36 -
38, The scopes migration defines a redundant index on org_name because the
uq_scopes_org_name unique constraint already creates a supporting index with
org_name as the leading column. Update the migration in the scopes table
creation block to remove idx_scopes_org and keep only the unique constraint, so
the schema avoids unnecessary write overhead while preserving lookup support via
the existing constraint-backed index.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@agent-manager-service/clients/thundersvc/identity_client.go`:
- Around line 925-1016: The `EnsureScopeResourceServer` path has a TOCTOU race:
concurrent callers can both miss the existing `amp-scopes` server and create
duplicates, and the same pattern exists when creating missing scope permissions.
Fix this by serializing the ensure logic per Thunder org/env +
`scopeResourceServerIdentifier` key, similar to `envThunderResolver.Resolve`’s
`singleflight` usage, so only one caller performs the create path at a time.
Keep the lock/singleflight only around the check-and-create decision, and avoid
holding it across network I/O longer than needed; the goal is to make
`findResourceServerID`/create and `listResourceServerPermissions`/create
effectively single-writer per key.

In `@agent-manager-service/controllers/agent_identity_controller.go`:
- Around line 311-327: `GetGroupRoles` and `GetRoleAssignments` are missing the
same not-found mapping used by the other single-resource handlers, so a missing
group/role currently becomes a generic 500. Update the error handling in
`agentIdentityController.GetGroupRoles` and
`agentIdentityController.GetRoleAssignments` to check
`thundersvc.IsNotFound(err)` before the fallback, and return a 404 with the
existing not-found response when that condition matches; keep the current 500
path for all other errors.
- Around line 650-668: The repository error is being discarded in
validateScopesInCatalog, which hides the real failure cause from
c.scopeRepo.List. Update the error handling in
agentIdentityController.validateScopesInCatalog to preserve the original error
by wrapping it with context instead of returning a generic error, so downstream
logs/debugging keep the DB/timeout details while still indicating scope catalog
loading failed.

In `@agent-manager-service/repositories/scope_repository.go`:
- Around line 74-82: Update scopeRepository.Update to mirror
scopeRepository.Delete by checking the RowsAffected from the
r.db.WithContext(ctx).Model(&models.Scope{}).Updates(...) call; if it is 0,
return the not-found sentinel mapped from gorm.ErrRecordNotFound (using
errors.Is for sentinel handling). Keep wrapping unexpected database errors with
context via fmt.Errorf, and preserve the existing Update method behavior for
successful writes.

In `@agent-manager-service/services/mcp_proxy_service.go`:
- Around line 855-862: ToolScopeBindings are being validated and persisted even
for environments without identity security, so add a guard in the
ToolScopeBindings handling path in mcp_proxy_service.go to reject these bindings
unless identity security is enabled. Update the validation logic in the
environment processing flow around the existing tool binding checks to return an
invalid-input error when identity/security is not configured, and apply the same
rule consistently in the related binding-check and persistence paths referenced
by the existing environment validation and save/update helpers. Use the existing
environment and binding symbols in this flow (such as ToolScopeBindings, envID,
and the surrounding environment validation functions) to keep the restriction
enforced everywhere bindings could otherwise be accepted.

In `@agent-manager-service/services/scope_service.go`:
- Around line 97-100: The reload step in the scope update flow is returning a
generic wrapped error instead of mapping a missing row to
utils.ErrScopeNotFound, so update the GetByName reload path in scope_service.go
to detect gorm.ErrRecordNotFound and return the same not-found error used
earlier in the method. Keep the existing context from the reload after
s.repo.Update, but ensure the retry/race case produces the 404-mapped
utils.ErrScopeNotFound rather than a 500-style failure.

---

Nitpick comments:
In `@agent-manager-service/db_migrations/029_create_scopes.go`:
- Around line 36-38: The scopes migration defines a redundant index on org_name
because the uq_scopes_org_name unique constraint already creates a supporting
index with org_name as the leading column. Update the migration in the scopes
table creation block to remove idx_scopes_org and keep only the unique
constraint, so the schema avoids unnecessary write overhead while preserving
lookup support via the existing constraint-backed index.

In `@agent-manager-service/docs/api_v1_openapi.yaml`:
- Around line 9548-10095: The agent-identity Thunder passthrough responses are
still modeled as generic object types, which limits generated client/console
type safety. Add minimally typed response schemas for the commonly used group
and role list/detail endpoints in the OpenAPI spec, and wire them into the
relevant operations such as listAgentIdentityGroups, getAgentIdentityGroup,
listAgentIdentityRoles, and getAgentIdentityRole. Keep the passthrough design
intact where needed, but replace the broad object responses with concrete
schemas wherever the Thunder shape is stable enough.

In `@agent-manager-service/services/scope_service_unit_test.go`:
- Around line 32-100: Add unit coverage in ScopeService tests for the missing
Create duplicate-conflict path and the Update flow. In the ScopeService.Create
test cases, mock ScopeRepositoryMock.GetByName to return an existing scope and
assert the result is utils.ErrConflict; also add a successful Create case that
verifies the repository write path is reached. Add ScopeService.Update tests for
both a successful update and the not-found branch by mocking ScopeRepositoryMock
accordingly, and use assert.ErrorIs/assert.NoError to validate the service’s own
sentinel behavior.

In `@console/apps/web-ui/public/config.js`:
- Around line 27-32: The scope allowlist is duplicated in the config and will
drift across environments, so replace the hand-maintained string in the scopes
configuration with a single source of truth generated from the canonical
permissions definition. Update the logic around the scopes field in config.js to
derive the list from rbac/permissions.go (or an equivalent shared generator) so
docker, Helm, and test configs consume the same emitted set instead of
separately copied scope strings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 0c868bcc-3d43-46b2-9474-83815128d72b

📥 Commits

Reviewing files that changed from the base of the PR and between d648a7b and 2ea85a0.

📒 Files selected for processing (64)
  • agent-manager-service/api/agent_identity_routes.go
  • agent-manager-service/api/app.go
  • agent-manager-service/api/scope_routes.go
  • agent-manager-service/clients/clientmocks/env_identity_client_mock.go
  • agent-manager-service/clients/clientmocks/env_thunder_resolver_fake.go
  • agent-manager-service/clients/thundersvc/env_resolver.go
  • agent-manager-service/clients/thundersvc/identity_client.go
  • agent-manager-service/clients/thundersvc/identity_client_test.go
  • agent-manager-service/clients/thundersvc/identity_types.go
  • agent-manager-service/controllers/agent_identity_controller.go
  • agent-manager-service/controllers/agent_identity_controller_unit_test.go
  • agent-manager-service/controllers/scope_controller.go
  • agent-manager-service/db_migrations/029_create_scopes.go
  • agent-manager-service/db_migrations/migration_list.go
  • agent-manager-service/docs/api_v1_openapi.yaml
  • agent-manager-service/models/llm_provider.go
  • agent-manager-service/models/mcp_proxy.go
  • agent-manager-service/models/scope.go
  • agent-manager-service/rbac/permissions.go
  • agent-manager-service/rbac/predefined_roles.go
  • agent-manager-service/repositories/agent_thunder_client_repository.go
  • agent-manager-service/repositories/repomocks/agent_thunder_client_repository_mock.go
  • agent-manager-service/repositories/repomocks/scope_repository_mock.go
  • agent-manager-service/repositories/scope_repository.go
  • agent-manager-service/services/mcp_proxy_deployment.go
  • agent-manager-service/services/mcp_proxy_deployment_test.go
  • agent-manager-service/services/mcp_proxy_service.go
  • agent-manager-service/services/mcp_proxy_service_unit_test.go
  • agent-manager-service/services/scope_service.go
  • agent-manager-service/services/scope_service_unit_test.go
  • agent-manager-service/spec/api_agent_identity.go
  • agent-manager-service/spec/api_scopes.go
  • agent-manager-service/spec/client.go
  • agent-manager-service/spec/model_agent_identity_agent_list_response.go
  • agent-manager-service/spec/model_agent_identity_agent_response.go
  • agent-manager-service/spec/model_agent_identity_assignments_request.go
  • agent-manager-service/spec/model_agent_identity_assignments_request_assignments_inner.go
  • agent-manager-service/spec/model_agent_identity_group_request.go
  • agent-manager-service/spec/model_agent_identity_members_request.go
  • agent-manager-service/spec/model_agent_identity_role_request.go
  • agent-manager-service/spec/model_identity_security.go
  • agent-manager-service/spec/model_mcp_environment_config.go
  • agent-manager-service/spec/model_mcp_proxy_request.go
  • agent-manager-service/spec/model_mcp_proxy_response.go
  • agent-manager-service/spec/model_mcp_tool_scope_binding.go
  • agent-manager-service/spec/model_scope_list_response.go
  • agent-manager-service/spec/model_scope_request.go
  • agent-manager-service/spec/model_scope_response.go
  • agent-manager-service/spec/model_scope_update_request.go
  • agent-manager-service/spec/model_security_config.go
  • agent-manager-service/utils/constants.go
  • agent-manager-service/utils/errors.go
  • agent-manager-service/wiring/params.go
  • agent-manager-service/wiring/wire.go
  • agent-manager-service/wiring/wire_gen.go
  • console/apps/web-ui/public/config.js
  • deployments/docker-compose.yml
  • deployments/helm-charts/wso2-agent-manager/values.yaml
  • deployments/helm-charts/wso2-amp-thunder-extension/values.yaml
  • docs/superpowers/plans/2026-07-07-mcp-proxy-agent-identity-security.md
  • docs/superpowers/plans/2026-07-07-preflight-notes.md
  • docs/superpowers/specs/2026-07-06-mcp-proxy-agent-identity-security-design.md
  • docs/superpowers/specs/2026-07-07-env-thunder-grant-verification.md
  • test/e2e/framework/auth.go

Comment thread agent-manager-service/clients/thundersvc/identity_client.go
Comment thread agent-manager-service/controllers/agent_identity_controller.go
Comment thread agent-manager-service/controllers/agent_identity_controller.go
Comment thread agent-manager-service/repositories/scope_repository.go
Comment thread agent-manager-service/services/mcp_proxy_service.go
Comment thread agent-manager-service/services/scope_service.go

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
agent-manager-service/services/scope_service_unit_test.go (1)

92-103: 🗄️ Data Integrity & Integration | 🟠 Major | ⚡ Quick win

Map repo.Delete not-found to utils.ErrScopeNotFound
agent-manager-service/repositories/scope_repository.go returns gorm.ErrRecordNotFound when Delete affects zero rows, but scopeService.Delete forwards that error unchanged. DeleteScope only translates utils.ErrScopeNotFound, so a concurrent delete still becomes a 500 instead of a 404. Mirror the Update mapping and add a unit test for the delete-after-get race.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@agent-manager-service/services/scope_service_unit_test.go` around lines 92 -
103, scopeService.Delete currently lets a repo-level not-found escape as
gorm.ErrRecordNotFound instead of utils.ErrScopeNotFound, so map the delete path
the same way Update does. In scope_service.go, update Delete to translate the
repository not-found from Delete (and any delete-after-get race handled through
DeleteScope) into utils.ErrScopeNotFound before returning. Add or extend a unit
test alongside TestScopeService_Delete_MissingScopeNotFound to cover the case
where GetByName succeeds but repo.Delete returns not found, using the
scopeService.Delete and DeleteScope flow to verify the mapping.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@agent-manager-service/services/scope_service_unit_test.go`:
- Around line 92-103: scopeService.Delete currently lets a repo-level not-found
escape as gorm.ErrRecordNotFound instead of utils.ErrScopeNotFound, so map the
delete path the same way Update does. In scope_service.go, update Delete to
translate the repository not-found from Delete (and any delete-after-get race
handled through DeleteScope) into utils.ErrScopeNotFound before returning. Add
or extend a unit test alongside TestScopeService_Delete_MissingScopeNotFound to
cover the case where GetByName succeeds but repo.Delete returns not found, using
the scopeService.Delete and DeleteScope flow to verify the mapping.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: 9b6bf8a1-cf2f-4977-a1c9-ec8ebed6e585

📥 Commits

Reviewing files that changed from the base of the PR and between 2ea85a0 and 3a32f59.

📒 Files selected for processing (10)
  • agent-manager-service/clients/thundersvc/identity_merge.go
  • agent-manager-service/clients/thundersvc/identity_merge_test.go
  • agent-manager-service/controllers/agent_identity_controller.go
  • agent-manager-service/controllers/agent_identity_controller_unit_test.go
  • agent-manager-service/controllers/identity_controller.go
  • agent-manager-service/repositories/scope_repository.go
  • agent-manager-service/services/mcp_proxy_service.go
  • agent-manager-service/services/mcp_proxy_service_unit_test.go
  • agent-manager-service/services/scope_service.go
  • agent-manager-service/services/scope_service_unit_test.go
✅ Files skipped from review due to trivial changes (1)
  • agent-manager-service/clients/thundersvc/identity_merge_test.go
🚧 Files skipped from review as they are similar to previous changes (5)
  • agent-manager-service/repositories/scope_repository.go
  • agent-manager-service/controllers/agent_identity_controller.go
  • agent-manager-service/services/mcp_proxy_service_unit_test.go
  • agent-manager-service/services/scope_service.go
  • agent-manager-service/services/mcp_proxy_service.go

@jhivandb jhivandb force-pushed the task/mcp-proxy-agent-identity branch from 505ea84 to d1280f3 Compare July 8, 2026 06:46
@jhivandb jhivandb changed the title [Draft] Add MCP proxy Agent Identity Add MCP proxy Agent Identity Jul 8, 2026
jhivandb added 12 commits July 8, 2026 12:26
Thunder's PUT /roles/{id} and /groups/{id} are full replaces, so the
per-field payload construction in the role/group update handlers
silently dropped unset fields (ouId, permissions, name). Route all four
handlers through shared NewRoleReplace/NewGroupReplace helpers that carry
the current ouId and permissions and preserve name/description when the
body omits them.

Also reject duplicate MCP tool-scope bindings for the same tool in
validateMCPEnvironments, and map scope-catalog Update misses to
not-found and Create duplicate-key races to conflict instead of 500.
Serialize EnsureScopeResourceServer's check-then-create paths to avoid
duplicate Thunder resource servers under concurrent calls, map
GetGroupRoles/GetRoleAssignments not-found to 404, log the swallowed
scope catalog load error, and reject persisted tool scope bindings
when identity security isn't enabled.
@jhivandb jhivandb force-pushed the task/mcp-proxy-agent-identity branch from d1280f3 to 0d3f210 Compare July 8, 2026 06:56
jhivandb added 2 commits July 8, 2026 13:38
register-amp-resources.sh was missing scope, agent-identity, agent-kind,
profile and the mcp-server/agent api-key-manage actions; the Helm
60-amp-resource-server.sh was missing scope and agent-identity. Add them
so both scripts register the full 104-permission catalog from rbac, and
add scope/agent-identity to the default roles in 61-amp-default-roles.sh
to match rbac/predefined_roles.go. Fix the stale permission counts.
Resolve conflicts from upstream's org_name -> ou_id migration:
- Renumber our migration029 (create scopes) to migration031; upstream now
  owns 029 (add ou_id) and 030 (swap constraints to ou_id)
- Migrate agent-identity picker to ou_id: FindByOrgAndEnvironment ->
  FindByOuAndEnvironment, ListAgents resolves ouID via OUIDFromRequest
- Re-wire ProvideEnvThunderResolver for AgentIdentityController (upstream
  de-wired it; our controller is a new production consumer)
- Regenerate wire, repository mocks, and CLI client

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
agent-manager-service/repositories/repomocks/agent_thunder_client_repository_mock.go (1)

1-1: 📐 Maintainability & Code Quality | 🟡 Minor | ⚡ Quick win

Add the Apache license header to this generated mock. The file starts with the moq comment only; prepend the standard Apache header so it matches the repository requirement.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In
`@agent-manager-service/repositories/repomocks/agent_thunder_client_repository_mock.go`
at line 1, Add the standard Apache license header to the generated mock so the
file begins with the repository’s required copyright/license block before the
moq-generated comment; update the top of agent_thunder_client_repository_mock.go
accordingly and keep the existing generated marker intact.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In
`@agent-manager-service/repositories/repomocks/agent_thunder_client_repository_mock.go`:
- Line 1: Add the standard Apache license header to the generated mock so the
file begins with the repository’s required copyright/license block before the
moq-generated comment; update the top of agent_thunder_client_repository_mock.go
accordingly and keep the existing generated marker intact.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: d6af2171-32fb-43fc-8839-f0fe1bab0117

📥 Commits

Reviewing files that changed from the base of the PR and between 8b558a8 and 738b69c.

⛔ Files ignored due to path filters (1)
  • cli/pkg/clients/amsvc/gen/types.gen.go is excluded by !**/gen/**
📒 Files selected for processing (14)
  • agent-manager-service/controllers/agent_identity_controller.go
  • agent-manager-service/controllers/agent_identity_controller_unit_test.go
  • agent-manager-service/db_migrations/031_create_scopes.go
  • agent-manager-service/db_migrations/migration_list.go
  • agent-manager-service/docs/api_v1_openapi.yaml
  • agent-manager-service/repositories/agent_thunder_client_repository.go
  • agent-manager-service/repositories/repomocks/agent_thunder_client_repository_mock.go
  • agent-manager-service/services/mcp_proxy_deployment.go
  • agent-manager-service/services/mcp_proxy_service.go
  • agent-manager-service/wiring/wire.go
  • agent-manager-service/wiring/wire_gen.go
  • console/apps/web-ui/public/config.js
  • deployments/docker-compose.yml
  • deployments/helm-charts/wso2-agent-manager/values.yaml
💤 Files with no reviewable changes (5)
  • agent-manager-service/wiring/wire.go
  • deployments/docker-compose.yml
  • deployments/helm-charts/wso2-agent-manager/values.yaml
  • agent-manager-service/wiring/wire_gen.go
  • console/apps/web-ui/public/config.js
🚧 Files skipped from review as they are similar to previous changes (5)
  • agent-manager-service/services/mcp_proxy_deployment.go
  • agent-manager-service/controllers/agent_identity_controller_unit_test.go
  • agent-manager-service/services/mcp_proxy_service.go
  • agent-manager-service/controllers/agent_identity_controller.go
  • agent-manager-service/docs/api_v1_openapi.yaml

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.

1 participant