Configuration
All TAP configuration is stored in SQLite and managed through the admin API. Credential values are encrypted at rest with AES-256-GCM. There is no YAML config file.
On managed hosting, the admin dashboard at auth.toolsec.org provides a visual interface for all these operations. Self-hosted deployments have a built-in dashboard at /dashboard. The admin API documented below works identically on both and is useful for automation and scripting.
Admin Authentication
Before making any configuration changes, you need an admin session token.
Sign Up
curl -X POST $PROXY_URL/signup \
-H "Content-Type: application/json" \
-d '{
"team_name": "my-team",
"email": "admin@example.com",
"password": "your-password"
}'This creates a team and an admin account. A verification email is sent with a 6-digit code.
Team names must be 3-64 characters, lowercase alphanumeric with hyphens. Passwords must be at least 8 characters.
Verify Email
curl -X POST $PROXY_URL/verify-email \
-H "Content-Type: application/json" \
-d '{"email": "admin@example.com", "code": "123456"}'Log In
curl -X POST $PROXY_URL/login \
-H "Content-Type: application/json" \
-d '{"email": "admin@example.com", "password": "your-password"}'Returns a session token valid for 24 hours:
{
"session_token": "a1b2c3...",
"admin_id": "uuid",
"team_id": "uuid",
"expires_at": "2026-04-03T12:00:00Z"
}Use the session token for all admin API calls:
export ADMIN_TOKEN="<session_token>"Log Out
curl -X POST $PROXY_URL/logout \
-H "Authorization: Bearer $ADMIN_TOKEN"Credentials
Credentials are the secrets that agents use through the proxy. Each credential belongs to a team and has a name, connector type, and encrypted value.
Create a Credential
curl -X POST $PROXY_URL/admin/credentials \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "slack",
"description": "Slack Bot Token",
"connector": "direct",
"api_base": "https://slack.com/api",
"value": "xoxb-your-slack-token"
}'| Field | Type | Default | Description |
|---|---|---|---|
name | string | required | Unique name within the team. Agents reference this in X-TAP-Credential |
description | string | required | Human-readable description |
connector | "direct" or "sidecar" | "direct" | Routing strategy (see How It Works) |
api_base | string | none | Base URL for the API. Required for sidecar connectors |
relative_target | bool | false | When true, X-TAP-Target is a path prepended with api_base. Requires connector: "sidecar" |
auth_header_format | string | "Bearer {value}" | Authorization header format for direct connectors. Use {value} as the placeholder |
value | string | none | The secret value. Write-only — never returned by any API endpoint |
List Credentials
curl $PROXY_URL/admin/credentials \
-H "Authorization: Bearer $ADMIN_TOKEN"Returns credential metadata only. Values are never included:
{
"credentials": [
{
"name": "slack",
"description": "Slack Bot Token",
"connector": "direct",
"api_base": "https://slack.com/api",
"relative_target": false,
"has_value": true
}
]
}Delete a Credential
curl -X DELETE $PROXY_URL/admin/credentials/slack \
-H "Authorization: Bearer $ADMIN_TOKEN"Deleting a credential cascades to remove it from all roles, agent assignments, and policies.
Agents
Agents are the AI systems that send requests through the proxy. Each agent belongs to a team, has an API key, and can access a set of credentials (via direct assignment or roles).
Create an Agent
curl -X POST $PROXY_URL/admin/agents \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"id": "social-agent",
"description": "Posts to Slack and Twitter",
"credentials": ["slack", "twitter"],
"roles": ["reader"],
"rate_limit_per_hour": 100
}'The response includes the API key, which is shown only once:
{
"id": "social-agent",
"api_key": "a1b2c3d4...",
"message": "Save this API key — it will not be shown again."
}| Field | Type | Default | Description |
|---|---|---|---|
id | string | required | Unique agent name within the team |
description | string | none | Human-readable description |
credentials | string[] | none | Credential names to assign directly |
roles | string[] | none | Roles to assign (agent inherits their credentials) |
rate_limit_per_hour | int | unlimited | Max requests per hour (429 if exceeded) |
List Agents
curl $PROXY_URL/admin/agents \
-H "Authorization: Bearer $ADMIN_TOKEN"Get Agent Details
curl $PROXY_URL/admin/agents/social-agent \
-H "Authorization: Bearer $ADMIN_TOKEN"Returns the agent’s details and effective credential set (union of direct assignments and roles):
{
"id": "social-agent",
"description": "Posts to Slack and Twitter",
"enabled": true,
"rate_limit_per_hour": 100,
"effective_credentials": ["github", "slack", "twitter"]
}Enable / Disable an Agent
# Disable (blocks all requests)
curl -X POST $PROXY_URL/admin/agents/social-agent/disable \
-H "Authorization: Bearer $ADMIN_TOKEN"
# Re-enable
curl -X POST $PROXY_URL/admin/agents/social-agent/enable \
-H "Authorization: Bearer $ADMIN_TOKEN"Delete an Agent
curl -X DELETE $PROXY_URL/admin/agents/social-agent \
-H "Authorization: Bearer $ADMIN_TOKEN"Roles (RBAC)
Roles group credentials together. Assign roles to agents instead of managing individual credential grants. An agent’s effective permissions are the union of its direct credential assignments and all its roles’ credentials.
Create a Role
curl -X POST $PROXY_URL/admin/roles \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "reader",
"description": "Read-only API access",
"credentials": ["slack", "github"],
"rate_limit_per_hour": 50
}'List Roles
curl $PROXY_URL/admin/roles \
-H "Authorization: Bearer $ADMIN_TOKEN"Delete a Role
curl -X DELETE $PROXY_URL/admin/roles/reader \
-H "Authorization: Bearer $ADMIN_TOKEN"Deleting a role cascades to remove it from all agent assignments.
CLI Alternative
The tap CLI provides the same operations:
tap role create --name reader --description "Read-only access" --credentials slack,github --rate-limit 50
tap agent create --name my-agent --roles reader --credentials extra-credSee CLI Reference for all commands.
Policies
Policies control which requests are auto-approved and which require human approval. They are set per-credential.
Set a Policy
curl -X PUT $PROXY_URL/admin/policies/slack \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"auto_approve_methods": ["GET"],
"require_approval_methods": ["POST", "PUT", "DELETE"],
"auto_approve_urls": ["/conversations.list", "/users.list"],
"allowed_approvers": ["123456789"],
"telegram_chat_id": "-100123456"
}'| Field | Type | Default | Description |
|---|---|---|---|
auto_approve_methods | string[] | [] | HTTP methods that skip approval. HEAD follows GET |
require_approval_methods | string[] | [] | HTTP methods that always require approval |
auto_approve_urls | string[] | [] | URL substrings that skip approval regardless of method |
allowed_approvers | string[] | [] | Telegram user IDs that can approve. Empty = anyone |
telegram_chat_id | string | global default | Override Telegram chat for this credential’s approvals |
Get a Policy
curl $PROXY_URL/admin/policies/slack \
-H "Authorization: Bearer $ADMIN_TOKEN"If a credential has no policy configured, all requests require approval. See Policies & Approval for evaluation order and examples.
Team Info
curl $PROXY_URL/admin/team \
-H "Authorization: Bearer $ADMIN_TOKEN"Returns your team’s ID, name, and creation date.
Notification Channels
Configure where approval messages are sent. Currently supports Telegram with additional channels planned.
Create a Notification Channel
curl -X POST $PROXY_URL/admin/notification-channels \
-H "Authorization: Bearer $ADMIN_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "ops-channel",
"channel_type": "telegram",
"config": {"chat_id": "-100123456", "bot_token": "optional-override"}
}'List Notification Channels
curl $PROXY_URL/admin/notification-channels \
-H "Authorization: Bearer $ADMIN_TOKEN"Delete a Notification Channel
curl -X DELETE $PROXY_URL/admin/notification-channels/ops-channel \
-H "Authorization: Bearer $ADMIN_TOKEN"Validation Rules
The proxy validates configuration and rejects invalid states:
- Agent credential references must exist in the team’s database
connector: "sidecar"requiresapi_baseto be setrelative_target: truerequiresconnector: "sidecar"- Credential and agent names must be unique within a team
- Team names must be globally unique, lowercase alphanumeric with hyphens