Roadmap

Aegis is small on purpose. Everything below is judged by one question: does it earn its place in a component whose value comes from having very little surface?

v1 — done

Identity

OAuth 2.1 authorization server with discovery, dynamic client registration, PKCE, a login form, and refresh rotation with family invalidation on reuse.

Transport

MCP over Streamable HTTP on port 2019, JSON-RPC with batches, session ids bound to their access token, DNS-rebinding protection on Origin.

Authorisation

Deny-by-default target matching on host, path glob and method, per-user allow_any, per-target rate limits, and a network guard that no user can disable.

Mediation

Declarative injection into headers, query parameters and JSON bodies; response redaction, truncation and cookie stripping; one audit line per request.

Operations

Config hot-reload on file change and SIGHUP that keeps the old config on a bad edit, a validate subcommand, and a distroless image that runs read-only as non-root.

Assurance

Race-enabled tests, a fuzz-style leak harness, govulncheck in CI, and multi-arch images with signed build provenance.

Under consideration

None of these are promised. Each would be added only if it turns out to be needed in practice.

IdeaWhy it might be worth it
Trusted proxies for the client IP Behind Traefik or Cloudflare, per-IP rate limiting collapses into a single bucket. A configured list of proxy addresses whose X-Forwarded-For may be believed would fix it. See the client IP problem.
Response filters per target Allow-listed JSON paths, so only the part of a response the agent needs reaches the context. Shrinks both the token bill and the exfiltration surface — at the cost of maintaining a filter per endpoint.
Per-target tool generation An opt-in that turns a target into its own named tool, improving the model's aim on a busy config.
Optional persistence For deployments that value uptime over amnesia and would rather not have every client re-register after a restart.
mTLS or IP allow-listing A second factor in front of the MCP endpoint, for aegis instances exposed to the open internet.
Audit log shipping Webhook or syslog output, so the record survives the container that produced it.
Request approval Hold a request until a human confirms it — useful for a target with write access that you are not ready to trust unattended.
Form-encoded body injection Today body injection is JSON only. application/x-www-form-urlencoded is common enough that it may deserve support.

Deliberately rejected

A web admin UI

Every form that edits secrets is a new way to leak them. The config file is the interface.

Request transformation

Aggregation, caching, schema translation. That is an API gateway, and it is a different product.

A plugin system

Arbitrary code in the process that holds the credentials — the opposite of the point.

Model-placed secrets

Letting the model decide where a secret goes hands placement back to the manipulable component.

Being a secret manager

No rotation, no versioning, no checkout. Point env: and file: at Vault or Docker secrets instead.

Multi-tenant SaaS

Aegis is a personal or small-team component. That assumption keeps the code readable.

Open questions

Decisions not yet made. Opinions welcome in an issue.

  1. Token revocation on password change. Today, changing a password does not invalidate existing tokens — they were issued against a prior successful authentication. Should a per-user revoke_on_password_change exist, or should it simply be the default?
  2. Describing allow_any to the model. How should an unrestricted user's permission be presented in list_targets so the model does not simply start guessing URLs?
  3. Refresh token lifetime. Thirty days is an arbitrary choice. Configurable per user, or a shorter fixed default?
  4. Streaming responses. v1 buffers a whole response in order to redact it, so downloads are bounded by max_response_bytes. Is a streaming redactor with a sliding window worth the complexity?
  5. The 8-byte redaction floor. Currently a startup warning. Should a secret too short to redact refuse to load at all?

Contributing

Issues and pull requests are welcome. The bar for new surface is deliberately high — if a change adds a configuration key, a dependency or an endpoint, the pull request should say what it buys and what it costs.

shell
git clone https://github.com/andreaskasper/aegis
cd aegis/src
go test -race ./...
go vet ./... && gofmt -l .
go run . validate ../config.example.yaml

CI enforces formatting, vet, a tidy go.mod, race-enabled tests, govulncheck, and that the image builds and answers /healthz while refusing unauthenticated MCP calls.