Configuration

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"
  }'
FieldTypeDefaultDescription
namestringrequiredUnique name within the team. Agents reference this in X-TAP-Credential
descriptionstringrequiredHuman-readable description
connector"direct" or "sidecar""direct"Routing strategy (see How It Works)
api_basestringnoneBase URL for the API. Required for sidecar connectors
relative_targetboolfalseWhen true, X-TAP-Target is a path prepended with api_base. Requires connector: "sidecar"
auth_header_formatstring"Bearer {value}"Authorization header format for direct connectors. Use {value} as the placeholder
valuestringnoneThe 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."
}
FieldTypeDefaultDescription
idstringrequiredUnique agent name within the team
descriptionstringnoneHuman-readable description
credentialsstring[]noneCredential names to assign directly
rolesstring[]noneRoles to assign (agent inherits their credentials)
rate_limit_per_hourintunlimitedMax 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-cred

See 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"
  }'
FieldTypeDefaultDescription
auto_approve_methodsstring[][]HTTP methods that skip approval. HEAD follows GET
require_approval_methodsstring[][]HTTP methods that always require approval
auto_approve_urlsstring[][]URL substrings that skip approval regardless of method
allowed_approversstring[][]Telegram user IDs that can approve. Empty = anyone
telegram_chat_idstringglobal defaultOverride 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" requires api_base to be set
  • relative_target: true requires connector: "sidecar"
  • Credential and agent names must be unique within a team
  • Team names must be globally unique, lowercase alphanumeric with hyphens