A lightweight credential proxy for AI agent workflows. Sits between your agent and any API — injecting real secrets at the network boundary. The agent never sees credentials.
Single-binary Go runtime with a compact footprint: ~17 MB executable, ~660 KB repo size, and ~76 KB internal source.
Works natively as an MCP server with Cursor, Claude Desktop, VS Code / Cline, and Windsurf.
- Version:
2.0.0 - License: Apache 2.0
- Code of Conduct: Contributor Covenant
- Releases: No releases published
- Packages: No packages published
- Tags: View tags
Agent context / system prompt:
GITHUB_TOKEN=ghp_abc123 ← agent can read this
STRIPE_SECRET_KEY=sk_... ← one prompt injection and it's gone
Agent ──► http://localhost:8080 ──► Aegis ──► api.github.com
(no key visible) │
└── pulls GITHUB_TOKEN from Infisical
at request time, never stored locally
go install github.com/yagna-1/aegis/cmd/aegis@latestOr install a prebuilt binary from the v2.0.0 release:
# macOS (Apple Silicon)
curl -L https://github.com/yagna-1/aegis/releases/download/v2.0.0/aegis-darwin-arm64 -o aegis
chmod +x aegis && sudo mv aegis /usr/local/bin/aegis
# macOS (Intel)
curl -L https://github.com/yagna-1/aegis/releases/download/v2.0.0/aegis-darwin-amd64 -o aegis
chmod +x aegis && sudo mv aegis /usr/local/bin/aegis
# Linux (amd64)
curl -L https://github.com/yagna-1/aegis/releases/download/v2.0.0/aegis-linux-amd64 -o aegis
chmod +x aegis && sudo mv aegis /usr/local/bin/aegis# Windows (PowerShell)
Invoke-WebRequest -Uri "https://github.com/yagna-1/aegis/releases/download/v2.0.0/aegis-windows-amd64.exe" -OutFile "aegis.exe"# Optional: verify checksums
curl -L https://github.com/yagna-1/aegis/releases/download/v2.0.0/checksums.txt -o checksums.txt
shasum -a 256 aegiscd ~/projects/my-agent
aegis init -services github,slack,stripe# Sign up free at https://app.infisical.com
# Create a Machine Identity with Universal Auth
# (Guide: https://infisical.com/docs/documentation/platform/identities/universal-auth)
aegis infisical setup
# → stores Client ID + Secret in your OS keychain
# → your actual API secrets stay in Infisical, never on diskinfisical:
project_id: your-project-id
environment: devIn the Infisical dashboard, add GITHUB_TOKEN, STRIPE_SECRET_KEY, etc.
aegis status # checks connection + shows which secrets are found
aegis # start proxy on :8080Infisical dashboard
→ stores GITHUB_TOKEN, STRIPE_SECRET_KEY, etc.
→ your actual secrets never touch your machine's filesystem
aegis infisical setup
→ stores only the Machine Identity credentials in OS keychain
→ two values: Client ID (not secret) + Client Secret
aegis starts
→ authenticates with Infisical API using Machine Identity
→ fetches all secrets into process memory
→ auto-refreshes every 5 minutes (rotated secrets propagate automatically)
Agent calls http://localhost:8080
→ Aegis injects the real credential header
→ forwards to allowlisted domain
→ agent sees the API response, never the key
Aegis auto-discovers aegis.yaml by walking up from the working directory — like .git:
~/projects/
stripe-app/
aegis.yaml ← infisical.environment: prod, allowlist: api.stripe.com only
github-bot/
aegis.yaml ← infisical.environment: dev, allowlist: api.github.com only
MCP mode inherits the IDE's working directory. Open a different project → different Infisical environment → different secrets. No flags needed.
| Source | How | Behavior |
|---|---|---|
| Infisical | infisical: block in aegis.yaml |
Strict mode: required if configured; startup fails if Infisical cannot load |
| OS Keychain | ${keychain:name} in templates |
Supported for template expansion at request time |
| .env file | Auto-discovered in project root | Used only when infisical: is not configured |
For agent-safe setups, use Infisical + keychain and avoid storing API keys in local .env files.
One config, works for all projects (auto-discovers per-project aegis.yaml).
Claude Desktop — ~/Library/Application Support/Claude/claude_desktop_config.json:
{
"mcpServers": {
"aegis": { "command": "aegis", "args": ["-mode", "mcp"] }
}
}Cursor — .cursor/mcp.json:
{
"mcpServers": {
"aegis": { "command": "aegis", "args": ["-mode", "mcp"] }
}
}VS Code / Cline / Windsurf — same pattern, check your tool's MCP config path.
The IDE spawns aegis -mode mcp as a child process automatically. The agent calls the http_request tool — no auth headers, no secrets in context.
# .env or system prompt instruction for the agent:
# "Call http://localhost:8080 with header X-Aegis-Target set to the full URL"
curl http://localhost:8080 \
-H "X-Aegis-Target: https://api.github.com/user/repos"Works with Python, TypeScript, Go, Ruby — any HTTP client.
Config: /projects/my-agent/aegis.yaml
Port: 8080
Secrets: Infisical
Site: https://app.infisical.com
Project: abc123
Env: dev
Status: ✓ connected, 8 secrets available
Allowlist (5 domains):
• api.github.com
• api.stripe.com
• slack.com
Credentials (3 configured):
• api.github.com Authorization: ✓ loaded
• api.stripe.com Authorization: ✓ loaded
• slack.com Authorization: ✓ loaded
| Threat | Mitigation |
|---|---|
| Agent reads secrets from context | Secrets in Infisical — never in agent context or disk |
| Agent exfiltrates credential via API | Domain allowlist — 403 for anything not listed |
| Agent sets its own auth header (MCP) | Explicitly rejected with error |
| Runaway agent burns API credits | Per-domain rate limit — configurable 429 |
| Prompt injection causes looping | Loop detection + X-Aegis-Warning header |
| Audit trail | NDJSON log — every request recorded, values never logged |
| Secret rotation | Infisical secrets refresh every 5 min — rotations propagate automatically |
Infisical is MIT-licensed and fully self-hostable. Point Aegis at your own instance:
infisical:
site_url: https://secrets.your-company.com
project_id: your-project-id
environment: devNo data ever leaves your infrastructure.
Your MCP command path is wrong. Point to an existing binary:
{
"mcpServers": {
"aegis": {
"command": "/path/to/aegis/dist/aegis-darwin-arm64",
"args": ["-mode", "mcp", "-config", "/path/to/project/aegis.yaml"]
}
}
}Either create one:
aegis init -services openaiOr pass an explicit path with -config /absolute/path/to/aegis.yaml.
project_id must be the actual Infisical Project ID (UUID-like), not slug/name.
Get it from Infisical Project Settings.
Assign your Machine Identity to the project and grant read access for the target environment/path.
This is expected in strict mode. When infisical: is configured, Aegis fails closed if Infisical auth/secret load fails.
.env fallback is only used when infisical: is not configured.
aegis statusLook for:
Status: ✓ connected, ... secrets availableCredentials ... Authorization: ✓ loaded
Apache 2.0