OAuth 1.0a Signer
The agentsec-signer crate is a standalone sidecar that signs requests with OAuth 1.0a (HMAC-SHA1, RFC 5849). Use it for APIs that require OAuth 1.0a authentication, like the Twitter/X API.
How It Works
TAP Proxy OAuth Signer Twitter API
| | |
| POST / | |
| X-OAuth-Credential: twitter | |
| X-OAuth-Target: https://... | |
| X-TAP-Method: POST | |
| body: {"text":"Hello"} | |
| ------------------------------>| |
| | Signs with HMAC-SHA1 |
| | POST https://... |
| | Authorization: OAuth .. |
| | ------------------------>|
| | |
| | Response |
| <--------------|<-------------------------|- Receives a request with
X-OAuth-Credential(credential name) andX-OAuth-Target(real API URL) - Loads the credential’s consumer key, consumer secret, access token, and access token secret from env vars
- Builds an OAuth 1.0a signature (nonce, timestamp, signature base string, HMAC-SHA1)
- Forwards the request to the real API with the signed
Authorizationheader - Returns the upstream response (auth headers stripped)
Setup
1. Configure TAP
Register the credential via the admin API or CLI. The credential uses the sidecar connector pointing at the signer.
Via admin API:
curl -X POST https://proxy.toolsec.org/admin/credentials \
-H "Authorization: Bearer $SESSION_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"name": "twitter",
"description": "Twitter API v2",
"connector": "sidecar",
"api_base": "http://oauth-signer:8080"
}'Via CLI (self-hosted):
tap add \
--db agentsec.db \
--encryption-key $AGENTSEC_ENCRYPTION_KEY \
--name twitter \
--description "Twitter API v2" \
--auth oauth1 \
--api-base http://oauth-signer:80802. Set Environment Variables
Each credential requires four env vars following this pattern:
OAUTH_CRED_{NAME}_CONSUMER_KEY=your-consumer-key
OAUTH_CRED_{NAME}_CONSUMER_SECRET=your-consumer-secret
OAUTH_CRED_{NAME}_ACCESS_TOKEN=your-access-token
OAUTH_CRED_{NAME}_ACCESS_TOKEN_SECRET=your-access-token-secretThe signer auto-discovers credentials by scanning for OAUTH_CRED_*_CONSUMER_KEY env vars at startup.
Example for Twitter:
OAUTH_CRED_TWITTER_CONSUMER_KEY=xvz1evFS4wEEPTGEFPHBog
OAUTH_CRED_TWITTER_CONSUMER_SECRET=kAcSOqF21Fu85e7zjz7ZN2U4ZRhfV3WpwPAoE3Z7kBw
OAUTH_CRED_TWITTER_ACCESS_TOKEN=370773112-GmHxMAgYyLbNEtIKZeRNFsMKPR9EyMZeS9weJAEb
OAUTH_CRED_TWITTER_ACCESS_TOKEN_SECRET=LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE3. Add to Docker Compose
services:
oauth-signer:
build:
context: .
dockerfile: Dockerfile.signer # or use the same Dockerfile with different target
ports:
- "8080:8080"
environment:
- OAUTH_SIGNER_PORT=8080
- OAUTH_CRED_TWITTER_CONSUMER_KEY
- OAUTH_CRED_TWITTER_CONSUMER_SECRET
- OAUTH_CRED_TWITTER_ACCESS_TOKEN
- OAUTH_CRED_TWITTER_ACCESS_TOKEN_SECRET4. Test
# Check signer health (lists discovered credentials)
curl http://localhost:8080/health
# Post a tweet through TAP
curl -X POST https://proxy.toolsec.org/forward \
-H "X-TAP-Key: $MY_AGENT_KEY" \
-H "X-TAP-Credential: twitter" \
-H "X-TAP-Target: https://api.twitter.com/2/tweets" \
-H "X-TAP-Method: POST" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from TAP!"}'Signer API
| Endpoint | Method | Description |
|---|---|---|
/ | ANY | Sign and forward request. Requires X-OAuth-Credential and X-OAuth-Target headers |
/health | GET | Health check, returns list of loaded credentials |
Port: Configurable via OAUTH_SIGNER_PORT (default 8080).
The X-TAP-Method header tells the signer which HTTP method to use for signing and forwarding (since the proxy always sends via POST).