Skip to main content

Overview

Gateway admin endpoints provide local management for:
  • Connections - CRUD operations for HTTP and MCP connectors
  • Credential Variables - Shared secrets reusable across connections
  • Service Catalog - Templates for quick connection setup
  • Testing & Discovery - Validate connections and discover MCP tools
Admin endpoints are intended for trusted local environments. Configure GATEWAY_ADMIN_ACCESS_MODE appropriately for your deployment.

Admin Access Modes

Gateway supports three admin access trust models:

Hybrid Mode (Default)

GATEWAY_ADMIN_ACCESS_MODE=hybrid
GATEWAY_ADMIN_TOKEN=strong_random_token_here
Allows requests from:
  • Loopback addresses (127.0.0.1, ::1), OR
  • Any IP with valid Authorization: Bearer <GATEWAY_ADMIN_TOKEN> header

Loopback Mode

GATEWAY_ADMIN_ACCESS_MODE=loopback
Only allows requests from loopback addresses. Rejects all other requests.

Token Mode

GATEWAY_ADMIN_ACCESS_MODE=token
GATEWAY_ADMIN_TOKEN=strong_random_token_here
Requires valid admin token from all requests regardless of source IP.
GATEWAY_ADMIN_TOKEN is required when using token or hybrid mode.

Signed Admin Checks

Test and discovery endpoints can require Sigilum-signed requests:
GATEWAY_REQUIRE_SIGNED_ADMIN_CHECKS=true  # Default: true
When enabled:
  • POST /api/admin/connections/{id}/test requires signature headers + approved claim
  • POST /api/admin/connections/{id}/discover requires signature headers + approved claim
Set to false only for trusted local maintenance.

Connections

List Connections

Response

connections
array
required
Array of connection objects

Example Request

curl -X GET http://localhost:38100/api/admin/connections

Example Response

{
  "connections": [
    {
      "id": "slack-proxy",
      "name": "Slack",
      "protocol": "http",
      "base_url": "https://slack.com/api",
      "path_prefix": "",
      "auth_mode": "bearer",
      "auth_header_name": "Authorization",
      "auth_prefix": "Bearer ",
      "status": "active",
      "created_at": "2026-03-01T10:00:00Z",
      "updated_at": "2026-03-01T10:00:00Z",
      "last_tested_at": "2026-03-04T09:00:00Z",
      "last_test_status": "success",
      "last_test_http_status": 200,
      "secret_version": 1
    },
    {
      "id": "linear-mcp",
      "name": "Linear MCP",
      "protocol": "mcp",
      "base_url": "https://mcp.linear.app",
      "mcp_transport": "streamable_http",
      "mcp_endpoint": "/mcp",
      "auth_mode": "bearer",
      "status": "active",
      "created_at": "2026-03-02T10:00:00Z",
      "updated_at": "2026-03-02T10:00:00Z",
      "mcp_discovery": {
        "server": {
          "name": "linear-mcp-server",
          "version": "1.0.0",
          "protocol_version": "2024-11-05"
        },
        "tools": [
          {
            "name": "linear.searchIssues",
            "description": "Search Linear issues"
          }
        ],
        "last_discovered_at": "2026-03-04T09:30:00Z"
      },
      "secret_version": 1
    }
  ]
}

Create Connection

Request Body

id
string
required
Unique connection identifier (alphanumeric, hyphens, underscores)
name
string
required
Human-readable connection name
protocol
string
default:"http"
Protocol type: http or mcp
base_url
string
required
Upstream base URL (e.g., https://slack.com/api)
path_prefix
string
Optional path prefix prepended to all requests
auth_mode
string
required
Authentication mode: bearer, header_key, or query_param
auth_header_name
string
required
Header name for auth injection (e.g., Authorization, X-API-Key)
auth_prefix
string
Prefix for auth value (e.g., Bearer for OAuth tokens)
auth_secret_key
string
Key name in secrets object to use for auth (HTTP connections require this)
secrets
object
required
Credential key-value pairs (encrypted before storage)Example: {"bot_token": "xoxb-123", "api_key": "{{SHARED_KEY}}"}
rotation_interval_days
integer
Credential rotation interval in days (for rotation enforcement)
mcp_transport
string
MCP transport protocol (currently only streamable_http supported)
mcp_endpoint
string
MCP endpoint path or full URL (for protocol: "mcp")
mcp_tool_allowlist
array<string>
Connection-level tool allowlist (only these tools exposed)
mcp_tool_denylist
array<string>
Connection-level tool denylist (these tools blocked)
mcp_max_tools_exposed
integer
Maximum tools to expose (truncate additional tools)
mcp_subject_tool_policies
object
Per-subject tool policies keyed by sigilum-subject valueExample:
{
  "user_alice": {
    "allowlist": ["linear.searchIssues"],
    "denylist": ["linear.deleteIssue"]
  }
}

Example: HTTP Connection

curl -X POST http://localhost:38100/api/admin/connections \
  -H 'Content-Type: application/json' \
  -d '{
    "id": "slack-proxy",
    "name": "Slack",
    "protocol": "http",
    "base_url": "https://slack.com/api",
    "auth_mode": "bearer",
    "auth_header_name": "Authorization",
    "auth_prefix": "Bearer ",
    "auth_secret_key": "bot_token",
    "secrets": {
      "bot_token": "xoxb-1234567890-abcdefghij"
    },
    "rotation_interval_days": 90
  }'

Example: MCP Connection with Shared Variable

curl -X POST http://localhost:38100/api/admin/connections \
  -H 'Content-Type: application/json' \
  -d '{
    "id": "linear-mcp",
    "name": "Linear MCP",
    "protocol": "mcp",
    "base_url": "https://mcp.linear.app",
    "mcp_transport": "streamable_http",
    "mcp_endpoint": "/mcp",
    "auth_mode": "bearer",
    "auth_header_name": "Authorization",
    "auth_prefix": "Bearer ",
    "auth_secret_key": "api_key",
    "secrets": {
      "api_key": "{{LINEAR_API_KEY}}"
    },
    "mcp_tool_allowlist": ["linear.searchIssues", "linear.getIssue"],
    "mcp_tool_denylist": ["linear.deleteIssue"]
  }'
Shared variable references use {{VARIABLE_NAME}} syntax. Define variables first via /api/admin/credential-variables.

Response (201 Created)

{
  "id": "slack-proxy",
  "name": "Slack",
  "protocol": "http",
  "base_url": "https://slack.com/api",
  "auth_mode": "bearer",
  "auth_header_name": "Authorization",
  "auth_prefix": "Bearer ",
  "status": "active",
  "created_at": "2026-03-04T11:00:00Z",
  "updated_at": "2026-03-04T11:00:00Z",
  "secret_version": 1
}

Get Connection

id
string
required
Connection identifier

Example Request

curl -X GET http://localhost:38100/api/admin/connections/slack-proxy

Response

Returns the connection object (same structure as List Connections).
Secrets are never returned in GET responses. Only metadata is included.

Update Connection

id
string
required
Connection identifier

Request Body

All fields are optional. Only provided fields are updated.
name
string
Update connection name
status
string
Update status: active or disabled
path_prefix
string
Update path prefix
auth_mode
string
Update auth mode
mcp_tool_allowlist
array<string>
Update MCP tool allowlist
mcp_tool_denylist
array<string>
Update MCP tool denylist
mcp_subject_tool_policies
object
Update per-subject tool policies

Example: Disable Connection

curl -X PATCH http://localhost:38100/api/admin/connections/slack-proxy \
  -H 'Content-Type: application/json' \
  -d '{"status": "disabled"}'

Example: Update MCP Policies

curl -X PATCH http://localhost:38100/api/admin/connections/linear-mcp \
  -H 'Content-Type: application/json' \
  -d '{
    "mcp_tool_allowlist": ["linear.searchIssues", "linear.getIssue", "linear.createIssue"],
    "mcp_subject_tool_policies": {
      "admin_bob": {
        "allowlist": ["linear.*"]
      },
      "user_alice": {
        "denylist": ["linear.createIssue", "linear.deleteIssue"]
      }
    }
  }'

Delete Connection

id
string
required
Connection identifier

Example Request

curl -X DELETE http://localhost:38100/api/admin/connections/slack-proxy

Response (204 No Content)

Empty response on success.
Deletion is permanent and cannot be undone. Secrets are wiped from encrypted storage.

Rotate Connection Secret

id
string
required
Connection identifier

Request Body

secrets
object
required
New credential key-value pairs
rotated_by
string
Subject who performed rotation (for audit trail)
rotation_reason
string
Reason for rotation (e.g., scheduled, compromised, manual)

Example Request

curl -X POST http://localhost:38100/api/admin/connections/slack-proxy/rotate \
  -H 'Content-Type: application/json' \
  -d '{
    "secrets": {
      "bot_token": "xoxb-new-token-xyz789"
    },
    "rotated_by": "admin_bob",
    "rotation_reason": "scheduled"
  }'

Response

{
  "id": "slack-proxy",
  "last_rotated_at": "2026-03-04T11:30:00Z",
  "next_rotation_due_at": "2026-06-02T11:30:00Z",
  "secret_version": 2
}
Rotation updates last_rotated_at, increments secret_version, and recalculates next_rotation_due_at based on rotation_interval_days.

Test Connection

id
string
required
Connection identifier

Request Body

method
string
default:"GET"
HTTP method for test request
test_path
string
required
Upstream path to test (e.g., /auth.test for Slack)
headers
object
Additional headers for test request
body
string
Request body for POST/PUT tests
When GATEWAY_REQUIRE_SIGNED_ADMIN_CHECKS=true, this endpoint requires Sigilum signature headers and approved claim.

Example Request

curl -X POST http://localhost:38100/api/admin/connections/slack-proxy/test \
  -H 'Content-Type: application/json' \
  -d '{
    "method": "GET",
    "test_path": "/auth.test"
  }'

Response (Success)

{
  "status": "success",
  "http_status": 200
}

Response (Failure)

{
  "status": "failure",
  "http_status": 401,
  "error": "invalid_auth"
}

Discover MCP Tools

id
string
required
MCP connection identifier (must have protocol: "mcp")
refresh
string
default:"force"
Refresh mode:
  • force - Bypass cache and refresh from upstream (default for admin discovery)
  • auto - Use cache policy (TTL + stale-if-error)
When GATEWAY_REQUIRE_SIGNED_ADMIN_CHECKS=true, this endpoint requires Sigilum signature headers and approved claim.

Example Request

curl -X POST 'http://localhost:38100/api/admin/connections/linear-mcp/discover?refresh=force'

Response

{
  "server": {
    "name": "linear-mcp-server",
    "version": "1.0.0",
    "protocol_version": "2024-11-05"
  },
  "tools": [
    {
      "name": "linear.searchIssues",
      "description": "Search Linear issues by text query",
      "input_schema": "{\"type\":\"object\",\"properties\":{\"query\":{\"type\":\"string\"}},\"required\":[\"query\"]}"
    },
    {
      "name": "linear.getIssue",
      "description": "Get a specific Linear issue by ID",
      "input_schema": "{\"type\":\"object\",\"properties\":{\"id\":{\"type\":\"string\"}},\"required\":[\"id\"]}"
    },
    {
      "name": "linear.createIssue",
      "description": "Create a new Linear issue",
      "input_schema": "{\"type\":\"object\",\"properties\":{\"title\":{\"type\":\"string\"},\"description\":{\"type\":\"string\"}},\"required\":[\"title\"]}"
    }
  ],
  "last_discovered_at": "2026-03-04T12:00:00Z"
}
Run discovery after creating a new MCP connection to populate available tools. Update allowlist/denylist based on discovered tools.

Credential Variables

Shared credential variables allow reusing secrets across multiple connections.

List Credential Variables

Response

variables
array
required
Array of credential variable metadata

Example Response

{
  "variables": [
    {
      "key": "OPENAI_API_KEY",
      "created_at": "2026-03-01T10:00:00Z",
      "updated_at": "2026-03-01T10:00:00Z",
      "created_by_subject": "admin_bob"
    },
    {
      "key": "LINEAR_API_KEY",
      "created_at": "2026-03-02T10:00:00Z",
      "updated_at": "2026-03-02T10:00:00Z",
      "created_by_subject": "user_alice"
    }
  ]
}

Create/Update Credential Variable

Request Body

key
string
required
Variable key (uppercase recommended, e.g., OPENAI_API_KEY)
value
string
required
Secret value (encrypted before storage)
created_by_subject
string
Subject creating the variable (for audit trail)
If sigilum-subject header is present, it takes precedence over created_by_subject in request body.

Example Request

curl -X POST http://localhost:38100/api/admin/credential-variables \
  -H 'Content-Type: application/json' \
  -H 'sigilum-subject: admin_bob' \
  -d '{
    "key": "OPENAI_API_KEY",
    "value": "sk-proj-abc123xyz789def456ghi012jkl345mno678pqr901stu234vwx"
  }'

Response (201 Created)

{
  "key": "OPENAI_API_KEY",
  "created_at": "2026-03-04T12:15:00Z",
  "updated_at": "2026-03-04T12:15:00Z",
  "created_by_subject": "admin_bob"
}

Delete Credential Variable

key
string
required
Variable key to delete

Example Request

curl -X DELETE http://localhost:38100/api/admin/credential-variables/OPENAI_API_KEY

Response (204 No Content)

Empty response on success.
Deletion is permanent. Connections referencing {{OPENAI_API_KEY}} will fail until variable is recreated.

Service Catalog

Service catalog provides templates for quick connection setup.

Get Service Catalog

Response

version
string
required
Catalog schema version
services
array
required
Array of service templates

Example Response

{
  "version": "1.0",
  "services": [
    {
      "key": "slack",
      "label": "Slack",
      "description": "Slack workspace integration",
      "connection_id": "slack-proxy",
      "protocol": "http",
      "base_url": "https://slack.com/api",
      "auth_mode": "bearer",
      "auth_header_name": "Authorization",
      "auth_prefix": "Bearer ",
      "auth_secret_key": "bot_token",
      "default_test_path": "/auth.test",
      "default_test_method": "GET",
      "credential_fields": [
        {
          "key": "bot_token",
          "label": "Bot Token",
          "placeholder": "xoxb-...",
          "env_var": "SLACK_BOT_TOKEN",
          "secret": true,
          "required": true,
          "help": "OAuth bot token from Slack app settings"
        }
      ]
    },
    {
      "key": "linear-mcp",
      "label": "Linear (MCP)",
      "description": "Linear project management via MCP",
      "connection_id": "linear-mcp",
      "protocol": "mcp",
      "base_url": "https://mcp.linear.app",
      "mcp_transport": "streamable_http",
      "mcp_endpoint": "/mcp",
      "auth_mode": "bearer",
      "auth_header_name": "Authorization",
      "auth_prefix": "Bearer ",
      "auth_secret_key": "api_key",
      "credential_fields": [
        {
          "key": "api_key",
          "label": "Linear API Key",
          "placeholder": "lin_api_...",
          "env_var": "LINEAR_API_KEY",
          "secret": true,
          "required": true
        }
      ]
    }
  ]
}
The env_var field is a dashboard hint for shared variable detection. Gateway does not automatically read from host environment variables.

Update Service Catalog

Request Body

Full catalog JSON (same structure as GET response).
This endpoint replaces the entire catalog. Use only for bulk catalog management.

CLI Reference

Gateway includes a local CLI for direct connection management:

List Connections

go run ./apps/gateway/service/cmd/sigilum-gateway-cli list

Add HTTP Connection

go run ./apps/gateway/service/cmd/sigilum-gateway-cli add \
  --name Slack \
  --base-url https://slack.com/api \
  --auth-mode bearer \
  --auth-prefix "Bearer " \
  --auth-secret-key bot_token \
  --secret bot_token=xoxb-1234567890-abcdefghij

Add MCP Connection

go run ./apps/gateway/service/cmd/sigilum-gateway-cli add \
  --name LinearMCP \
  --protocol mcp \
  --base-url https://mcp.linear.app \
  --mcp-endpoint /mcp \
  --auth-secret-key api_key \
  --secret api_key=lin_api_xyz789 \
  --mcp-allow linear.searchIssues \
  --mcp-deny linear.deleteIssue

Test Connection

go run ./apps/gateway/service/cmd/sigilum-gateway-cli test \
  --id slack-proxy \
  --method GET \
  --path /auth.test

Rotate Credentials

go run ./apps/gateway/service/cmd/sigilum-gateway-cli rotate \
  --id slack-proxy \
  --secret bot_token=xoxb-new-token-xyz789

Delete Connection

go run ./apps/gateway/service/cmd/sigilum-gateway-cli delete --id slack-proxy
CLI reads GATEWAY_DATA_DIR and GATEWAY_MASTER_KEY from environment or accepts --master-key flag.

Configuration Variables

Key environment variables for admin operations:
VariableDefaultDescription
GATEWAY_ADMIN_ACCESS_MODEhybridAdmin access model: hybrid, loopback, or token
GATEWAY_ADMIN_TOKEN-Admin token (required for token/hybrid modes)
GATEWAY_REQUIRE_SIGNED_ADMIN_CHECKStrueRequire signatures for test/discover endpoints
GATEWAY_ALLOWED_ORIGINS-CORS allowed origins (comma-separated)
GATEWAY_DATA_DIR~/.local/share/sigilum-gatewayLocal data directory
GATEWAY_SERVICE_CATALOG_FILE$DATA_DIR/service-catalog.jsonService catalog path
GATEWAY_MASTER_KEY-Encryption key for secrets (base64-encoded)

Next Steps

Proxy Endpoints

Use configured connections for runtime requests

MCP Runtime

Execute MCP tools after discovery

Build docs developers (and LLMs) love