Verify access from your application
Once your roles, scopes, and bindings are set up, your protected Application (MCP server, API, AI agent) needs to ask AuthSec whether each incoming request is allowed.
You almost never write the introspection call by hand. Install the AuthSec SDK and let the wrapper handle token validation, scope resolution, and the deny taxonomy. The example below is the minimum manual path — useful for debugging or for runtimes the SDK doesn't cover yet.
Manual check (Python)
from authsec_sdk import HybridValidator, ScopeMatrixClient, Config
config = Config.from_env() # reads AUTHSEC_RESOURCE_URI, AUTHSEC_ISSUER, AUTHSEC_JWKS_URL, AUTHSEC_INTROSPECTION_*
validator = HybridValidator(config)
scopes = ScopeMatrixClient(config)
async def can_call_tool(bearer_token: str, tool_id: str) -> bool:
principal = await validator.validate(bearer_token)
if not principal.active:
return False
policy = await scopes.lookup_tool(tool_id)
return principal.has_any_scope(policy.required_any)
What the wrapper does for you
When you use mount_mcp() (Python), MountMCP() (Go), or mountMCP() (TypeScript), this entire flow is automatic:
- Extracts the bearer token from
Authorization: Bearer …. - Validates it (JWT signature + JWKS, or RFC 7662 introspection, depending on
validation_mode). - Looks up the tool in the scope matrix.
- Checks the token's scopes against the tool's required scopes.
- Returns the right denial code (
step_up_required,consent_required,policy_denied,scope_insufficient, …) so the AI client knows how to recover.
See the SDK guides for the 5-line wrapper that protects your Application end-to-end.
Debug a specific denial
If you want to see why a specific request was denied, paste the request's decision_id (returned in the denial body) into Effective Access in the admin UI. It shows every binding evaluated, every condition checked, and the first reason that failed.