This document explains how to authenticate with the StackOne API when using the Python SDK. Authentication is required for all operations, including tool discovery via MCP and tool execution. This page covers API key configuration, the authentication mechanism, and how credentials are attached to HTTP requests.
For information about configuring account IDs for multi-account filtering, see Dynamic Tool Filtering.
The SDK provides two methods for supplying your StackOne API key: environment variable configuration (recommended) or explicit parameter initialization.
The recommended approach is to set the STACKONE_API_KEY environment variable. The SDK automatically reads this variable during StackOneToolSet initialization:
The initialization logic attempts to read the environment variable if no explicit key is provided:
Sources: stackone_ai/toolset.py316-350 README.md54-59
Alternatively, you can pass the API key directly to the constructor. This approach is useful for programmatic credential management or testing:
The explicit parameter takes precedence over the environment variable:
Sources: stackone_ai/toolset.py316-343 tests/test_toolset.py172-177
If no API key is provided through either method, initialization raises a ToolsetConfigError:
Sources: stackone_ai/toolset.py340-343 tests/test_toolset.py185-191
The SDK uses HTTP Basic Authentication with the API key as the username and an empty password.
The _build_auth_header function constructs the Authorization header value:
Title: Basic Auth Header Construction
flowchart LR
APIKey["API Key<br/>(string)"]
Concat["Concatenate with ':'<br/>'api_key:'"]
Encode["Base64 Encode"]
Prefix["Prepend 'Basic '"]
Header["Authorization Header"]
APIKey --> Concat
Concat --> Encode
Encode --> Prefix
Prefix --> Header
The implementation performs these steps:
:) to the API key"Basic " to the encoded stringFor example, the API key "test_api_key" produces the header:
Authorization: Basic dGVzdF9hcGlfa2V5Og==
Sources: stackone_ai/toolset.py126-128 tests/test_toolset.py76-119
In addition to the Authorization header, the SDK includes a User-Agent header identifying the SDK version:
This header is constructed as "stackone-ai-python/{version}" where the version is extracted from package metadata.
Sources: stackone_ai/toolset.py57-60 stackone_ai/toolset.py68
Title: Authentication Flow from Initialization to HTTP Request
flowchart TD
Init["StackOneToolSet.__init__<br/>(api_key, account_id, base_url)"]
ReadEnv["Read STACKONE_API_KEY<br/>environment variable"]
ValidateKey["Validate API key present"]
StoreKey["Store api_key in instance"]
FetchTools["fetch_tools()"]
BuildMCPHeaders["_build_mcp_headers()"]
BuildAuthHeader["_build_auth_header(api_key)"]
MCPRequest["MCP HTTP Request<br/>(tool discovery)"]
CreateTool["_create_rpc_tool()"]
StoreToolKey["Store api_key in<br/>_StackOneRpcTool"]
ExecuteTool["tool.execute()"]
BuildActionHeaders["_build_action_headers()"]
RPCRequest["RPC HTTP Request<br/>(tool execution)"]
Init --> ReadEnv
ReadEnv --> ValidateKey
ValidateKey --> StoreKey
StoreKey --> FetchTools
FetchTools --> BuildMCPHeaders
BuildMCPHeaders --> BuildAuthHeader
BuildAuthHeader --> MCPRequest
FetchTools --> CreateTool
CreateTool --> StoreToolKey
StoreToolKey --> ExecuteTool
ExecuteTool --> BuildActionHeaders
BuildActionHeaders --> RPCRequest
When fetching tool definitions from the MCP backend, authentication headers are built in _build_mcp_headers:
This method constructs headers including:
Authorization: Basic auth header from _build_auth_header()User-Agent: SDK version identifierx-account-id: Optional account filter (if provided)Sources: stackone_ai/toolset.py806-813 tests/test_toolset.py260-280
For RPC tool execution, the API key is stored in each _StackOneRpcTool instance and used when making HTTP requests:
The RPC tool constructs action headers that include the account ID but not the Authorization header (which is handled by the base StackOneTool.execute method):
The base StackOneTool._prepare_headers method then adds the authorization:
Sources: stackone_ai/toolset.py171-198 stackone_ai/toolset.py243-256 stackone_ai/models.py139-156
In addition to API key authentication, the SDK supports account-level request routing through the x-account-id header.
Account IDs can be specified in three ways:
| Method | Code Location | Scope |
|---|---|---|
| Constructor parameter | StackOneToolSet(account_id="...") | All tools fetched |
set_accounts() method | toolset.set_accounts(["acc1", "acc2"]) | All tools fetched |
fetch_tools() parameter | fetch_tools(account_ids=["acc1"]) | Specific fetch call |
Sources: stackone_ai/toolset.py316-350 stackone_ai/toolset.py351-361 stackone_ai/toolset.py730-804
Title: Account ID Header Flow
flowchart LR
ToolsetInit["StackOneToolSet<br/>account_id='acc123'"]
FetchTools["fetch_tools()"]
MCPHeaders["_build_mcp_headers(account_id)"]
MCPRequest["MCP Request<br/>x-account-id: acc123"]
CreateTool["_create_rpc_tool<br/>(account_id='acc123')"]
ToolInstance["_StackOneRpcTool<br/>_account_id='acc123'"]
ExecuteTool["tool.execute()"]
ActionHeaders["_build_action_headers()"]
RPCRequest["RPC Request<br/>x-account-id: acc123"]
ToolsetInit --> FetchTools
FetchTools --> MCPHeaders
MCPHeaders --> MCPRequest
FetchTools --> CreateTool
CreateTool --> ToolInstance
ToolInstance --> ExecuteTool
ExecuteTool --> ActionHeaders
ActionHeaders --> RPCRequest
During MCP tool discovery, if an account ID is specified, it's included in the headers:
During RPC tool execution, the account ID is included in the action headers sent to the backend:
The account ID is also added to request headers in the base StackOneTool._prepare_headers method:
Sources: stackone_ai/toolset.py806-813 stackone_ai/toolset.py243-256 stackone_ai/models.py139-156
The RPC execution logic explicitly removes any Authorization header from user-provided headers to prevent header conflicts:
This ensures that authentication is controlled exclusively by the SDK's internal mechanisms.
Sources: stackone_ai/toolset.py243-256
The API key is stored as a plain string in the StackOneToolSet instance:
Each created tool also stores the API key as a private attribute:
stackone_ai/models.py93 stackone_ai/models.py127
Recommendation: Avoid logging or printing StackOneToolSet or StackOneTool instances, as they contain sensitive credentials.
The Basic auth mechanism uses Base64 encoding, which is not encryption. Base64-encoded credentials can be easily decoded. Always use HTTPS endpoints (the default https://api.stackone.com) to ensure credentials are transmitted securely.
When using the STACKONE_API_KEY environment variable:
.env files containing real credentials to version controlSources: stackone_ai/toolset.py338-343 stackone_ai/toolset.py126-128
The SDK defines a hierarchy of authentication-related errors:
| Exception | Inherits From | When Raised |
|---|---|---|
ToolsetConfigError | ToolsetError | Missing API key during initialization |
StackOneAPIError | StackOneError | HTTP authentication failures (401, 403) |
Example of missing API key error:
HTTP authentication errors during requests are caught and wrapped in StackOneAPIError with status code and response body information.
Sources: stackone_ai/toolset.py47-62 tests/test_toolset.py53-73 tests/test_models.py473-514
Refresh this wiki