Repository navigation
Conversation
The spec carries agent identity in `X-AMP-Agent-ID` and defines no credential (RFC-AMP-001 §6.1), so the header was an assertion rather than proof: anyone who could reach the port could claim any agent id, and every access rule downstream - `readable_by`, `writable_by`, the owner check - was decided from that claim. The reference server was exactly as documented, and unsafe on any network an operator does not fully control. This adds proof without changing the binding. The agent id keeps travelling in the header, where the spec puts it; with a key store configured, the caller must also present a key that belongs to that id. - `amp_server.auth` loads a store from `AMP_API_KEYS_FILE`: a JSON object mapping agent id to a `sha256:` digest. Digests, not keys, so a leaked file does not hand over working credentials; `python -m amp_server.auth hash <key>` prints the value to paste. - A wrong key, a missing key and a key for an agent that does not exist answer the same `401 UNAUTHENTICATED`, so the endpoints cannot be used to enumerate agent ids - the same reasoning as the uniform 403 on deleted cells in spec §8.4. - **Off by default**, so the spec's binding keeps working for anyone who has not opted in - and a store that cannot be read **stops the server** rather than falling back to trusting the header, which would silently remove the protection an operator asked for. - Identity resolution moved into one FastAPI dependency (`verified_agent_id`), so a route cannot resolve an agent without proving it, and a route added later fails the sweep test rather than shipping unverified. - `POST /memories`'s `identity.created_by` fallback is closed whenever keys are configured. That fallback is the documented default without keys; with them it would have been an authentication bypass, letting any caller create a cell as any agent. The test for it was written after tracing what the fallback does, not after assuming it was inert. - `GET /spec` reports `api_keys_required`, so a client learns it needs a key before a call fails with 401. `GET /health` and `/spec` stay open. - Both SDKs take the key as a constructor argument. Their identity headers are now built in one method instead of at each call site - the async client was setting `X-AMP-Agent-ID` in four places, which is four places to forget a credential.
Owner
Author
|
Landed on master in the v0.1.0 chain: the branch was fast-forward merged as part of |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
feat(server): optional API-key authentication for the HTTP binding
The spec carries agent identity in
X-AMP-Agent-IDand defines no credential(RFC-AMP-001 §6.1), so the header was an assertion rather than proof: anyone who
could reach the port could claim any agent id, and every access rule downstream -
readable_by,writable_by, the owner check - was decided from that claim. Thereference server was exactly as documented, and unsafe on any network an operator
does not fully control.
This adds proof without changing the binding. The agent id keeps travelling in the
header, where the spec puts it; with a key store configured, the caller must also
present a key that belongs to that id.
amp_server.authloads a store fromAMP_API_KEYS_FILE: a JSON object mappingagent id to a
sha256:digest. Digests, not keys, so a leaked file does nothand over working credentials;
python -m amp_server.auth hash <key>prints thevalue to paste.
same
401 UNAUTHENTICATED, so the endpoints cannot be used to enumerate agentids - the same reasoning as the uniform 403 on deleted cells in spec §8.4.
opted in - and a store that cannot be read stops the server rather than
falling back to trusting the header, which would silently remove the protection
an operator asked for.
verified_agent_id), soa route cannot resolve an agent without proving it, and a route added later
fails the sweep test rather than shipping unverified.
POST /memories'sidentity.created_byfallback is closed whenever keys areconfigured. That fallback is the documented default without keys; with them it
would have been an authentication bypass, letting any caller create a cell as
any agent. The test for it was written after tracing what the fallback does, not
after assuming it was inert.
GET /specreportsapi_keys_required, so a client learns it needs a keybefore a call fails with 401.
GET /healthand/specstay open.built in one method instead of at each call site - the async client was setting
X-AMP-Agent-IDin four places, which is four places to forget a credential.