Skip to main content

Scope Mismatch Detection

Scope mismatch detection identifies annotations where the declared axag-scope is inconsistent with the operation's actual access pattern, tenant model, or role requirements.

Why It Matters

Scope mismatches can cause:

  • Cross-tenant data leakage — An operation scoped to global that should be scoped to tenant
  • Privilege escalation — An operation scoped to user that actually modifies tenant-wide settings
  • Broken authorization — Roles defined for one scope applied in another
  • Agent over-reach — An agent invoking operations beyond its authorized boundary

Common Scope Mismatches

1. Missing Scope on Tenant-Sensitive Operations

❌ No scope — agent can't determine tenant boundary
<!-- ❌ No scope declared — agent doesn't know tenant boundary -->
<button
axag-intent="user.list"
axag-entity="user"
axag-action-type="read"
axag-required-roles='["admin"]'
>List All Users</button>

Rule: AXAG-LINT-004 — Operations with role requirements MUST declare a scope.

Fix:

✅ Fix — add tenant scope
<button
axag-intent="user.list"
axag-entity="user"
axag-action-type="read"
axag-required-roles='["admin"]'
axag-scope="tenant"
>List All Users</button>

2. Global Scope on User-Specific Operations

❌ Global scope on personal action
<!-- ❌ Global scope on a personal action -->
<button
axag-intent="profile.update"
axag-entity="profile"
axag-action-type="write"
axag-scope="global"
axag-required-parameters='["user_id","display_name"]'
>Update Profile</button>

Rule: AXAG-LINT-018 — Operations on personal entities SHOULD use user scope, not global.

Fix:

✅ Fix — use user scope
<button
axag-intent="profile.update"
axag-entity="profile"
axag-action-type="write"
axag-scope="user"
axag-required-parameters='["display_name"]'
>Update Profile</button>

3. Tenant Scope Without Tenant-Aware Roles

<!-- ❌ Tenant scope but roles don't include tenant context -->
<button
axag-intent="settings.update"
axag-entity="settings"
axag-action-type="write"
axag-scope="tenant"
axag-required-roles='["superadmin"]'
>Update Settings</button>

Rule: AXAG-LINT-019superadmin roles typically imply global scope. Verify if tenant is correct.

4. Cross-Entity Scope Inconsistency

When two operations on the same page operate on the same entity but declare different scopes:

<!-- Operation 1: tenant scope -->
<button axag-intent="report.generate" axag-entity="report"
axag-action-type="read" axag-scope="tenant">Generate</button>

<!-- Operation 2: global scope (on same entity) -->
<button axag-intent="report.delete" axag-entity="report"
axag-action-type="delete" axag-scope="global">Delete</button>

Rule: AXAG-LINT-020 — Operations on the same entity within a page SHOULD use consistent scope unless justified.

Scope Hierarchy

global
└── tenant
└── team
└── user
ScopeMeaningTypical Operations
globalPlatform-wide, all tenantsSystem settings, platform analytics
tenantWithin a single tenant/organizationTeam management, tenant config, business data
teamWithin a team or departmentTeam-specific dashboards, shared resources
userPersonal to the current userProfile, preferences, personal data

Detection Rules Summary

RuleMismatchSeverity
AXAG-LINT-004Role requirements without scopeError
AXAG-LINT-018Global scope on personal operationsWarning
AXAG-LINT-019Scope/role hierarchy mismatchWarning
AXAG-LINT-020Inconsistent scope on same entityWarning
AXAG-LINT-021Delete operation without scopeError
AXAG-LINT-022Tenant mutation with user scopeError

CI Integration

- name: Check for scope mismatches
run: npx axag-lint --rules scope-mismatch --format=github

Next Steps