Skip to main content

AuthSec SDK for MCP auth, services, CIBA, and SPIFFE integration

Project description

AuthSec Python SDK (authsec_sdk)

Add OAuth + RBAC protection to MCP tools with minimal code changes.

This SDK lets you:

  • Protect MCP tools with @protected_by_AuthSec(...)
  • Register normal unprotected MCP tools with @mcp_tool(...)
  • Run an MCP server that delegates auth/tool listing to AuthSec SDK Manager
  • Access downstream service credentials safely through ServiceAccessSDK

What This SDK Does (and Why)

AuthSec is the control plane: users authenticate through AuthSec, show up in the AuthSec web app, and you assign them roles/permissions and conditional access policies.

This Python package is the enforcement layer for MCP:

  • It provides a minimal HTTP MCP server (run_mcp_server_with_oauth(...)) so you do not need to implement MCP transport + OAuth bootstrap tools yourself.
  • It delegates OAuth flows and authorization decisions to the hosted AuthSec SDK Manager.
  • It enforces allow/deny for protected tools at call time (the security boundary), and can also hide tools in tools/list as a UX improvement (policy controlled by AuthSec).

Why this approach:

  • B2B teams often have many internal tools. You configure identity + RBAC once in AuthSec, then every MCP tool can inherit the same enterprise policy without re-implementing Okta/SAML/SCIM in each server.
  • The SDK stays thin: your business logic stays in your tool handlers; AuthSec decides who can call them.

Package

  • Name: authsec-sdk
  • Import path: authsec_sdk
  • Python: >=3.10.11

Install

One command on macOS

From the repo:

bash scripts/bootstrap-python-sdk-macos.sh --client-id YOUR_CLIENT_ID

Using GitHub raw:

curl -fsSL https://raw.githubusercontent.com/authsec-ai/sdk-authsec/main/scripts/bootstrap-python-sdk-macos.sh | bash -s -- --client-id YOUR_CLIENT_ID

Notes:

  • Default install source is pypi.
  • Use --source https or --source ssh if you want to install directly from GitHub.
  • Add --run to start the sample server immediately after setup.

Local development

cd packages/python-sdk
python3 -m pip install -e .

From GitHub (advanced)

If you already cloned this repo, the shortest path is an editable install:

python3 -m pip install -e packages/python-sdk

If you need a one-command setup on macOS, use the bootstrap script above.

Direct pip install from GitHub monorepo (long command)
python3 -m venv .venv
source .venv/bin/activate
python3 -m pip install --upgrade pip
python3 -m pip install "git+ssh://git@github.com/authsec-ai/sdk-authsec.git@main#subdirectory=packages/python-sdk"

If you prefer HTTPS:

python3 -m pip install "git+https://github.com/authsec-ai/sdk-authsec.git@main#subdirectory=packages/python-sdk"

Windows PowerShell

py -3 -m venv .venv
.venv\Scripts\Activate.ps1
py -3 -m pip install --upgrade pip
py -3 -m pip install "git+https://github.com/authsec-ai/sdk-authsec.git@main#subdirectory=packages/python-sdk"

If your org uses GitHub SSH on Windows:

py -3 -m pip install "git+ssh://git@github.com/authsec-ai/sdk-authsec.git@main#subdirectory=packages/python-sdk"

From package index

python3 -m pip install authsec-sdk

Windows PowerShell

py -3 -m pip install authsec-sdk

Verify install

macOS / Linux

python3 -c "import authsec_sdk; print(authsec_sdk.__version__)"

Windows PowerShell

py -3 -c "import authsec_sdk; print(authsec_sdk.__version__)"

Quick Start

Create server.py:

from authsec_sdk import mcp_tool, protected_by_AuthSec, run_mcp_server_with_oauth


@mcp_tool(
    name="ping",
    description="Health check tool",
    inputSchema={
        "type": "object",
        "properties": {},
        "required": []
    }
)
async def ping(arguments: dict) -> list:
    return [{"type": "text", "text": "pong"}]


@protected_by_AuthSec(
    tool_name="delete_invoice",
    roles=["admin"],
    scopes=["write"],
    require_all=True,
    description="Delete invoice by id",
    inputSchema={
        "type": "object",
        "properties": {
            "invoice_id": {"type": "string"},
            "session_id": {"type": "string"}
        },
        "required": ["invoice_id"]
    }
)
async def delete_invoice(arguments: dict) -> list:
    invoice_id = arguments.get("invoice_id")
    user = (arguments.get("_user_info") or {}).get("email_id", "unknown-user")
    return [{"type": "text", "text": f"Deleted invoice {invoice_id} by {user}"}]


if __name__ == "__main__":
    import __main__

    run_mcp_server_with_oauth(
        user_module=__main__,
        client_id="YOUR_CLIENT_ID",
        app_name="my-python-mcp",
        host="127.0.0.1",
        port=3005,
    )

Run on macOS / Linux:

AUTHSEC_AUTH_SERVICE_URL="https://dev.api.authsec.dev/sdkmgr/mcp-auth" \
AUTHSEC_SERVICES_URL="https://dev.api.authsec.dev/sdkmgr/services" \
python3 server.py

Run on Windows PowerShell:

$env:AUTHSEC_AUTH_SERVICE_URL = "https://dev.api.authsec.dev/sdkmgr/mcp-auth"
$env:AUTHSEC_SERVICES_URL = "https://dev.api.authsec.dev/sdkmgr/services"
py -3 .\server.py

Connect MCP Inspector:

npx @modelcontextprotocol/inspector http://127.0.0.1:3005

Full setup by OS

macOS / Linux

  1. Create and activate a virtual environment.
  2. Install the SDK from GitHub or from a package index.
  3. Create server.py with from authsec_sdk import ....
  4. Export AUTHSEC_AUTH_SERVICE_URL and AUTHSEC_SERVICES_URL if you want to override the defaults.
  5. Run python3 server.py.
  6. Open MCP Inspector against http://127.0.0.1:3005.

Windows PowerShell

  1. Create and activate a virtual environment with py -3 -m venv .venv and .venv\Scripts\Activate.ps1.
  2. Install the SDK from GitHub or from a package index.
  3. Create server.py with from authsec_sdk import ....
  4. Set $env:AUTHSEC_AUTH_SERVICE_URL and $env:AUTHSEC_SERVICES_URL if you want to override the defaults.
  5. Run py -3 .\server.py.
  6. Open MCP Inspector against http://127.0.0.1:3005.

How Protection Works

  1. Server exposes OAuth tools from SDK Manager (oauth_start, oauth_authenticate, oauth_status, etc.).
  2. User authenticates and gets/uses a session.
  3. When a protected tool is called, SDK hits protect-tool upstream.
  4. RBAC is evaluated from your tool declaration (roles, groups, resources, scopes, permissions).
  5. On success, your handler receives:
  • arguments["session_id"] (resolved session)
  • arguments["_user_info"] (JWT/user claims)

Auth behavior note:

  • Auth decisions are delegated upstream to SDK Manager.
  • SDK may still expose OAuth tool schemas when upstream tools/list is unavailable so clients can continue auth bootstrap.

Decorators

@protected_by_AuthSec(...)

Use for tools that require auth/RBAC.

Key parameters:

  • tool_name
  • roles, groups, resources, scopes, permissions
  • require_all (default False; if True, all specified categories must match)
  • description
  • inputSchema

@mcp_tool(...)

Use for tools that should stay unprotected.

Key parameters:

  • name
  • description
  • inputSchema

Session-Aware Handler Pattern

If your protected function accepts a second session argument, SDK passes a simple session object:

@protected_by_AuthSec("service_call", scopes=["read"])
async def service_call(arguments: dict, session) -> list:
    # session.session_id, session.user_id, session.tenant_id, session.access_token
    return [{"type": "text", "text": session.session_id}]

Service Access SDK

Use ServiceAccessSDK(session) to fetch service credentials/tokens from SDK Manager services API:

from authsec_sdk import ServiceAccessSDK

@protected_by_AuthSec("fetch_github_token", scopes=["read"])
async def fetch_github_token(arguments: dict, session) -> list:
    services = ServiceAccessSDK(session)
    token = await services.get_service_token("github")
    return [{"type": "text", "text": f"Token length: {len(token)}"}]

Environment Variables

SDK runtime:

  • AUTHSEC_AUTH_SERVICE_URL (optional, default points to dev)
  • AUTHSEC_SERVICES_URL (optional, default points to dev)
  • AUTHSEC_TIMEOUT_SECONDS (default 15)
  • AUTHSEC_RETRIES (default 2)
  • AUTHSEC_TOOLS_LIST_TIMEOUT_SECONDS (default 8)

Note:

  • Tool visibility policies like AUTHSEC_ALWAYS_EXPOSE_PROTECTED_TOOLS / AUTHSEC_HIDE_UNAUTHORIZED_TOOLS are controlled in SDK Manager service config, not this package.

Troubleshooting

  • ModuleNotFoundError: No module named 'AuthSec_SDK'
    • The correct import is from authsec_sdk import .... The package name is authsec-sdk, but the Python import path is authsec_sdk.
  • Local folder named authsec_sdk shadows the installed package
    • Rename or remove the local folder before running your app. python path/to/script.py puts that script directory first on sys.path.
  • Apple Silicon Mac imports fail with incompatible architecture
    • Do not mix arm64 and x86_64 Python environments. Recreate the virtualenv using the same architecture you will run.
  • OAuth tool failed: ... released back to the pool
    • This is an SDK Manager backend deployment/version issue, not client SDK usage.
  • verifyToken failed: 404
    • Check SDK Manager AUTH_MANAGER_URL and ensure it targets your correct environment (dev vs prod).
  • Protected tools denied unexpectedly
    • Confirm JWT claims contain expected roles/scopes/resources and match your decorator RBAC.

Prompt Template (Copy/Paste)

Use this prompt with any coding LLM to wrap a Python MCP server with AuthSec:

You are editing a Python MCP server codebase.

Goal:
1) Integrate authsec_sdk so selected tools are protected with OAuth + RBAC.
2) Keep public tools unprotected.
3) Start server via run_mcp_server_with_oauth.

Requirements:
- Use @protected_by_AuthSec for sensitive tools.
- Use @mcp_tool for unprotected tools.
- Pass a clear inputSchema for each tool.
- Ensure protected handlers read user info from arguments["_user_info"].
- Keep all OAuth/auth checks delegated upstream (no local bypass/fallback logic).
- Add startup instructions using AUTHSEC_AUTH_SERVICE_URL and AUTHSEC_SERVICES_URL.

Inputs:
- client_id: <YOUR_CLIENT_ID>
- app_name: <YOUR_APP_NAME>
- protected tools + RBAC:
  - <tool_name_1>: roles=[...], scopes=[...], require_all=<true/false>
  - <tool_name_2>: ...
- unprotected tools:
  - <tool_name_3>

Deliverables:
- Updated Python source files.
- A runnable command section.
- A short verification checklist using MCP Inspector.

Publishing (Python)

One-command publish (recommended)

From the repo root:

# TestPyPI first
bash scripts/publish-python-sdk.sh --test

# Then PyPI
bash scripts/publish-python-sdk.sh

Auth for twine (do not commit tokens):

export TWINE_USERNAME="__token__"
export TWINE_PASSWORD="pypi-REDACTED"

1) Bump version

Update version consistently:

  • packages/python-sdk/pyproject.toml -> [project].version
  • packages/python-sdk/src/authsec_sdk/__init__.py -> __version__

2) Build artifacts

cd packages/python-sdk
python3 -m pip install --upgrade build twine
python3 -m build
python3 -m twine check dist/*

3) Test publish (recommended)

python3 -m twine upload --repository testpypi dist/*

Install from TestPyPI in a clean venv and run smoke test.

4) Publish to PyPI

python3 -m twine upload dist/*

5) Post-publish check

python3 -m pip install --upgrade authsec-sdk
python3 -c "import authsec_sdk; print(authsec_sdk.__version__)"

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

authsec_sdk-4.0.0.tar.gz (33.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

authsec_sdk-4.0.0-py3-none-any.whl (33.1 kB view details)

Uploaded Python 3

File details

Details for the file authsec_sdk-4.0.0.tar.gz.

File metadata

  • Download URL: authsec_sdk-4.0.0.tar.gz
  • Upload date:
  • Size: 33.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.1

File hashes

Hashes for authsec_sdk-4.0.0.tar.gz
Algorithm Hash digest
SHA256 b4cabc6a0a719a0a789ca47074a33e59230736597e3547f7ca1428aa1f172564
MD5 e973c028994db334d8454b25a08f463c
BLAKE2b-256 55f38917d91efc957a7d23339c1453c98e7604589977ac2a1971ca2642d498db

See more details on using hashes here.

File details

Details for the file authsec_sdk-4.0.0-py3-none-any.whl.

File metadata

  • Download URL: authsec_sdk-4.0.0-py3-none-any.whl
  • Upload date:
  • Size: 33.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.11.1

File hashes

Hashes for authsec_sdk-4.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e93b6dfa3d3fe8c6c238eae57c53391c1869fe6ff0803ef133eb3f14f89122b0
MD5 9d866ed7d4340a113659bb317a9a281f
BLAKE2b-256 a293fe5ab61d4b394fedf509517970616bcfef851c177b6bb87258135c03b4cd

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page