Repository navigation
Require a verified caller before a bound call is sent - #42
Conversation
The signer and the witness check an Ed25519 Wicket token, hash the caller id from the key file into call_digest, and enforce a per-caller grant. Used token ids are stored next to the witness log, so a replay after restart is IDENTITY_UNVERIFIED and nothing is sent. Co-authored-by: Jon Halstead <warheart1984@gmail.com>
Codex Review SummaryThis comment shows the latest Codex review activity on this pull request.
ℹ️ About Codex in GitHubYour team has set up Codex to review pull requests in this repo. Reviews are triggered when you
Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings. |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 2890a57c6f
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| if self.path.is_file(): | ||
| existing = self.path.read_text(encoding="utf-8").splitlines() | ||
| if jti in existing: | ||
| return False |
There was a problem hiding this comment.
Serialize token claims across witness processes
When two witness processes share a log directory, each has its own threading.Lock, so both can read the token-id file before either appends and both return success from commit. This is reproducible during an overlapping restart and allows the same token to authorize two distinct valid allow receipts for the same call, resulting in two dispatches despite the single-use-token guarantee. Use an inter-process file lock or another atomic claim operation around the read-and-append sequence.
Useful? React with 👍 / 👎.
| produces a matching allow and a witness performs the call. `WICKET_CALLER_KEY` is the caller's | ||
| private key. `WICKET_CALLER_KEYS` is the public map the signer and the witness trust. Whoever | ||
| can write that map can add callers. Direct `infinityctl evaluate` does not verify tokens. |
There was a problem hiding this comment.
Make the documented executor setup provide caller credentials
The runnable command immediately below this text still uses demo/policy.json, which has no callers grant, and it sets neither WICKET_CALLER_KEY nor WICKET_CALLER_KEYS. Following the documented setup therefore always yields IDENTITY_UNVERIFIED (and, after adding credentials alone, AUTHORITY_DENIED) instead of reaching the stated approval/allow flow. The example needs to create/configure a caller key map and use a policy containing a matching grant.
Useful? React with 👍 / 👎.
A bound call now requires
Authorization: Wicket <token>. The signer and the witness both verify the Ed25519 signature. The caller id that is stored and hashed is the id in the caller key file.call_digestincludes that id as the second length-prefixed field forhttps_requestandlocal_model_tool. Used token ids are written next to the witness log, so a replay is stillIDENTITY_UNVERIFIEDafter a new witness is opened on the same directory. A policycallersmap grants effects, target prefixes, risk, and action per caller id.WICKET_ALLOW_DIRECT_CALLS=1is unchanged: it still skips the witness, still warns, and still does not require a caller token.Proven
startedentry, and insidecall_digest.runtime/call_binding.pyandverifier/ickverify.pyagree. An omitted or forged caller id failsickverify.mismatch, nothing sent).IDENTITY_UNVERIFIEDand send nothing.IDENTITY_UNVERIFIEDand sends nothing, including after a new witness on the same log directory.IDENTITY_UNVERIFIEDand sends nothing.AUTHORITY_DENIEDand sends nothing.callersmap, the kernel still allows a read or write.infinityctl evaluatedoes not verify tokens. The witness refuses that receipt when no token is presented.Push CI on
2890a57c6f4075b6c0e062a3a4611437db892adbis green:Not proven
state_ref.User-Agentis sent and is not hashed. It names the HTTP library, and hashing it would split one call into many digests without authenticating anyone. The authorization header value is sent and not hashed. The raw token is not hashed. Streamed known-shape calls stay refused. The opt-out does not derive a digest. Directinfinityctl evaluatedoes not verify tokens.