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
AgentSec Proxy OAuth Signer Twitter API
│ │ │
│ POST / │ │
│ X-OAuth-Credential: twitter │ │
│ X-OAuth-Target: https://... │ │
│ X-AgentSec-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. 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=LswwdoUaIvS8ltyTt5jkRh4J50vUPVVHtR2YPi5kE2. Configure AgentSec
In agentsec.yaml, set up the credential with connector: sidecar pointing at the signer:
credentials:
twitter:
description: "Twitter API v2"
connector: sidecar
api_base: "http://oauth-signer:8080"
policies:
twitter:
auto_approve: ["GET"]
require_approval: ["POST", "PUT", "DELETE"]3. 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 AgentSec
curl -X POST http://localhost:3100/forward \
-H "X-AgentSec-Key: $MY_AGENT_KEY" \
-H "X-AgentSec-Credential: twitter" \
-H "X-AgentSec-Target: https://api.twitter.com/2/tweets" \
-H "X-AgentSec-Method: POST" \
-H "Content-Type: application/json" \
-d '{"text": "Hello from AgentSec!"}'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-AgentSec-Method header tells the signer which HTTP method to use for signing and forwarding (since the proxy always sends via POST).