Deployment
Managed vs Self-Hosted
TAP can run as a managed service or self-hosted. Both use the same proxy, the same API, and the same agent interface. From the agent’s perspective, switching deployments means changing one URL.
| Feature | Managed | Self-Hosted |
|---|---|---|
| Hardware enclave | Yes | No |
| Encryption key management | Handled by enclave | You generate and manage |
| Admin interface | Dashboard + API | Dashboard + API + CLI |
| TLS | Included | You configure |
| Cost | Usage-based | Free (you pay for infra) |
Managed hosting runs in Evervault hardware enclaves. Encryption keys are generated inside the enclave and never leave. Recommended for most users. Sign up at the dashboard and follow the Quickstart.
Self-hosted is MIT licensed. Full control, no external dependencies, free forever. You manage encryption keys, TLS, and updates.
Self-Hosted Setup
Local Development
git clone https://github.com/nanaknihal/agentsec
cd agentsec
cp local.env.example .env
# Edit .env — generate encryption key with: openssl rand -hex 32
docker-compose -f docker-compose.yaml -f docker-compose.local.yaml up --buildDashboard at http://localhost:3100/dashboard. Audit logs at ./data/audit.jsonl.
In local mode, if email sending fails, the verification code is logged to the Docker console.
Production
Includes nginx for TLS termination on port 443:
docker-compose up --build| Service | Port | Purpose |
|---|---|---|
proxy | 3100 (internal) | TAP proxy |
nginx | 443 (public) | TLS termination |
TLS Setup
- Place your certificate and key in
deploy/certs/(cert.pem,key.pem) - Configure
deploy/nginx.confwith your domain docker-compose up --build
Building from Source
cargo build --release
# Binary at target/release/agentsec-proxySet environment variables (see below) and run directly.
Health Check
curl http://localhost:3100/healthNo auth required. Docker Compose checks it every 30 seconds.
Environment Variables
Proxy (Required)
| Variable | Description |
|---|---|
AGENTSEC_ENCRYPTION_KEY | 64 hex chars (32 bytes). Used for HMAC-SHA256 agent key hashing and AES-256-GCM credential encryption. Generate with openssl rand -hex 32 |
TELEGRAM_BOT_TOKEN | Telegram bot token from @BotFather |
Proxy (Optional)
| Variable | Default | Description |
|---|---|---|
TELEGRAM_CHAT_ID | Default Telegram chat ID for approval messages. Teams can configure their own via the admin API | |
AGENTSEC_DB_PATH | ./agentsec.db | Path to the SQLite database |
AGENTSEC_AUDIT_LOG | ./audit.jsonl | Path to audit log file |
AGENTSEC_LISTEN_ADDR | 0.0.0.0:3100 | Listen address |
AGENTSEC_FORWARD_TIMEOUT_SECS | 30 | Timeout for upstream API requests (seconds) |
AGENTSEC_APPROVAL_TIMEOUT_SECS | 300 | Timeout waiting for human approval (seconds) |
AGENTSEC_CACHE_TTL_SECS | 30 | Cache TTL for DB lookups (seconds) |
WebAuthn (Optional)
For passkey-based approval (Face ID, fingerprint, YubiKey):
| Variable | Description |
|---|---|
WEBAUTHN_RP_ID | Relying party ID (e.g., toolsec.org) |
WEBAUTHN_RP_ORIGIN | Relying party origin (e.g., https://proxy.toolsec.org) |
WEBAUTHN_BASE_URL | Base URL for WebAuthn endpoints |
OAuth 1.0a Signer
Each OAuth 1.0a credential requires four env vars:
| Variable | Description |
|---|---|
OAUTH_CRED_{NAME}_CONSUMER_KEY | OAuth consumer key |
OAUTH_CRED_{NAME}_CONSUMER_SECRET | OAuth consumer secret |
OAUTH_CRED_{NAME}_ACCESS_TOKEN | OAuth access token |
OAUTH_CRED_{NAME}_ACCESS_TOKEN_SECRET | OAuth access token secret |
OAUTH_SIGNER_PORT | Signer listen port (default: 8080) |
Example: credential twitter uses OAUTH_CRED_TWITTER_CONSUMER_KEY, etc. The signer auto-discovers credentials by scanning for OAUTH_CRED_*_CONSUMER_KEY env vars at startup.
CLI Reference
The tap CLI manages credentials, agents, and roles via SQLite. Primarily useful for self-hosted deployments. For managed hosting, use the dashboard or admin API.
All management commands use --encryption-key (or AGENTSEC_ENCRYPTION_KEY env var) and --db (default ./agentsec.db).
tap add
Add a credential. Runs interactively if --name is omitted.
tap add \
--name slack \
--description "Slack API" \
--auth api-key \
--api-base https://slack.com/api| Flag | Description |
|---|---|
--name | Credential name |
--description | Human-readable description |
--auth | Auth type: api-key, oauth2, oauth1, custom |
--api-base | API base URL or sidecar URL |
--relative-target | Target is a relative path (for sidecars) |
tap status
Check proxy health.
tap status [--proxy-url http://localhost:3100]tap logs
Display formatted audit log entries.
tap logs [--log-file ./audit.jsonl] [--tail 20]tap agent
tap agent list # List all agents
tap agent create --name my-agent \ # Create agent (prints API key once)
--credentials slack,github \
--rate-limit 100
tap agent show my-agent # Show agent details + effective permissions
tap agent enable my-agent # Re-enable a disabled agent
tap agent disable my-agent # Disable (rejects all requests)
tap agent delete my-agent # Deletetap role
tap role list # List all roles
tap role create --name reader \ # Create role
--credentials slack,github \
--rate-limit 50
tap role add-credential reader slack # Grant credential to role
tap role remove-credential reader slack # Revoke credential from role
tap role delete reader # Delete (cascades to agents)Production Checklist
- TLS enabled
- Strong encryption key (not the example value)
- Unique API key per agent
- Audit log on persistent storage
- Policies reviewed per credential (start restrictive)
- Rate limits configured for high-volume agents
-
allowed_approversset for sensitive credentials