Frequently Asked Questions
Common questions and answers about the AuthSec SDK.
General Questions
What packages do I need to install?
Use the package for your language. The source repository is named sdk-authsec, but package managers use language-specific names.
| Package | Use case |
|---|---|
@authsec/sdk | TypeScript / JavaScript MCP servers, APIs, and agents |
authsec-sdk | Python MCP servers, APIs, agents, CIBA, and workload helpers |
github.com/authsec-ai/sdk-authsec/packages/go-sdk | Go MCP servers, APIs, and agents |
The older authz-sdk package was a separate RBAC helper surface. New MCP protection work should start with the runtime SDK pages: Python, TypeScript, or Go.
Is TypeScript/JavaScript support available?
Yes. Install @authsec/sdk and use the runtime-first mountMCP API. See the TypeScript SDK guide.
How do I get the SDK client credentials?
Create an Application in the AuthSec admin UI. The Application UUID is AUTHSEC_RESOURCE_SERVER_ID and AUTHSEC_INTROSPECTION_CLIENT_ID; the one-time secret is AUTHSEC_INTROSPECTION_CLIENT_SECRET.
MCP Servers & Clients
What does mount_mcp / mountMCP / MountMCP do?
The runtime mount wraps your existing MCP HTTP handler. It serves protected-resource metadata, validates bearer tokens, checks tool access against AuthSec's policy, publishes the SDK manifest, and attaches a principal to the downstream request.
from authsec_sdk import from_env, mount_mcp
cfg = from_env()
mount_mcp(app, "/mcp", existing_handler, cfg)
For new servers, prefer the runtime mount APIs. The legacy decorators still exist for older projects.
What about protected_by_AuthSec and run_mcp_server_with_oauth?
They are legacy compatibility APIs. They remain available for older integrations, but new Applications should use mount_mcp in Python, mountMCP in TypeScript, or MountMCP in Go.
Can I have tools that don't require authentication?
Yes. In AuthSec, public tool status is an operator policy decision. Publish the tool manifest, mark the tool public in the UI, and the runtime policy will allow it for any valid token for the Application.
Workload Identity (SPIRE / SVID)
What is a SPIFFE ID and SVID?
- SPIFFE ID — A URI that uniquely identifies a workload (e.g.
spiffe://example.com/workload/api-service). It is the workload's cryptographic identity. - SVID (SPIFFE Verifiable Identity Document) — A short-lived X.509 certificate that proves a workload's SPIFFE ID. SVIDs are rotated automatically.
The AuthSec SDK's QuickStartSVID handles fetching and rotating SVIDs so your code only needs to call:
svid = await QuickStartSVID.initialize()
print(svid.spiffe_id) # spiffe://...
print(svid.cert_file_path) # path to the certificate
When should I use workload identity instead of OAuth?
| Scenario | Recommended approach |
|---|---|
| A human user is authenticating via a client app or MCP server | OAuth / runtime SDK mount |
| A service or container needs to call another service with no human in the loop | Workload identity (SPIRE/SVID) |
| You need mTLS between microservices | Workload identity (SPIRE/SVID) |
Use workload identity for machine-to-machine (M2M) communication. Use OAuth for user-facing flows.
How does certificate auto-renewal work?
The ICP Agent running on your host maintains a live connection to the AuthSec SPIRE server. It automatically renews SVIDs before they expire (default renewal threshold is 6 hours before expiry). Your workload accesses the latest certificate through the SPIRE socket — no restart required.
Which deployment environments are supported for the ICP Agent?
The ICP Agent supports three deployment targets:
| Environment | Recommended method |
|---|---|
| Kubernetes | Helm chart (DaemonSet) |
| Docker | docker-compose with shared socket volume |
| VM (Linux) | Quick-install script or manual systemd service |
See Autonomous Workloads for step-by-step guides for each environment.
Why does the ICP Agent need SYS_PTRACE capability?
The SYS_PTRACE capability is required for process attestation — the agent inspects process metadata to cryptographically verify the identity of workloads running on the same host. This is how zero-trust attestation works without pre-shared secrets.
RBAC
What is the difference between a permission, a scope, and a role binding?
| Concept | Description | Example |
|---|---|---|
| Permission | A resource + action pair | invoice:create, document:read |
| Scope | A named group of permissions for a set of resources | api.documents.write |
| Role binding | Assigns a role (which has permissions) to a user | Binding editor role to user@example.com |
Permissions are the atomic units. Scopes group permissions for OAuth token grants. Role bindings connect users to roles that carry permissions.
What's the difference between check_permission and check_permission_scoped?
check_permission(resource, action)— Checks whether the authenticated user has the permission for the current workspace context.check_permission_scoped(resource, action, scope_type, scope_id)— Checks whether the user has the permission within a narrower application or resource scope.
# Global permission check
client.check_permission("document", "read")
# Project-scoped permission check
client.check_permission_scoped("document", "read", scope_type="project", scope_id="proj-123")
Use scoped checks when your application supports multiple applications or resources with isolated permissions.
Are permission checks performed locally or via an API call?
check_permission and check_permission_scoped perform local JWT checks — they decode and verify the user's JWT without making a network call. This makes permission enforcement fast and suitable for use in request handlers.
External Services & Secret Management
How does the SDK securely retrieve external service tokens?
The ServiceAccessSDK retrieves tokens from a secure vault managed by AuthSec. Your application never stores the external token directly — it requests it at runtime within an authenticated session:
services_sdk = ServiceAccessSDK(session)
github_token = await services_sdk.get_service_token("your_token")
This means external credentials are centrally managed and can be rotated without redeploying your application.
What external services can I integrate with?
Any external service that uses bearer token authentication (GitHub, Slack, Jira, etc.) can be integrated by storing that service's token in the AuthSec vault and retrieving it via ServiceAccessSDK.get_service_token(). The SDK acts as a secure credential broker between your workload and the external API.
Troubleshooting
QuickStartSVID.initialize() raises a RuntimeError
Cause: The SPIRE socket path is not configured or the ICP Agent is not running.
Solution:
- Verify the ICP Agent is healthy:
curl http://localhost:8080/healthz - Check the socket exists:
ls -l /run/spire/sockets/agent.sock - Pass the socket path explicitly:
svid = await QuickStartSVID.initialize(socket_path="/run/spire/sockets/agent.sock")
The ICP Agent pod keeps restarting on Kubernetes
Possible causes:
workspaceIdoricpServiceUrlare incorrect invalues.yaml- The pod cannot reach the AuthSec SPIRE service (network policy issue)
- Missing
SYS_PTRACEcapability in the security context
Diagnosis:
kubectl logs -n default -l app=icp-agent --tail=100
kubectl describe pod -n default -l app=icp-agent
check_permission always returns False
Possible causes:
- The
AUTHSEC_API_URLenvironment variable is not set - The user's JWT does not include the expected permission claim
- The permission was not created or assigned to the user's role
Solution: Confirm the permission exists and is bound to the correct role, then verify the user has that role assigned.
Support
Still have questions?
- Email: support@authsec.dev
- GitHub: github.com/authsec-ai
Next Steps
- MCP Servers & AI Agents — Integrate auth into your MCP server
- Autonomous Workloads — Configure workload identity
- Permissions & Resources — Enforce RBAC in your app
- Secret Management — Access external service tokens securely