Conversation
The keeper obtained its notarized reading through the notary crate's
`jwks` helpers, which made it depend on the whole notary server and pin
the notary's exact libid-rs revision so cargo kept one copy of the types.
The notary is client-agnostic -- it signs the same record for every
session -- so those helpers were always keeper code.
Move them in: `jwks::layout` (reveal both directions whole, commit
nothing), `jwks::prover::{run_jwks_prover, notarize_jwks}` over
`libid_tlsn::prover_generic`, and `jwks::mock::MockProver`, which
synthesizes a byte-faithful record without MPC for the end-to-end test;
plus `examples/notarize_jwks`, which captures a real reading as a fixture.
`NotarizedSession` is `libid_transcript::AttestationWire`, so the keeper
and the notary agree on the frame by construction. The module carries its
own error type, the notary's minus the server-only variants.
Manifest: drop `notary`; libid-crypto and libid-signer move from rev
391078f to tag v0.3.0, joined by libid-tlsn, libid-transcript and
libid-ceremony at the same tag. Running the MPC prover means carrying the
TLSNotary fork pin (libid-org/tlsn 550220e) and, because cargo ignores
dependency-workspace patches, the same 24-entry libid-org/mpz patch block
the notary carries; the two move together.
Assisted-by: Claude Fable 5.1
Signed-off-by: xgreenx <xgreenx9999@gmail.com>
This was referenced Sep 14, 2026
Review of the move found leftovers from the module's notary origins, none
functional:
* the module doc pinned [`NotarizedSession`] to `crate::NotarizedSession`,
where the notary re-exported it; here the alias lives in this module,
so the bare link resolves and the definition line goes (cargo doc was
warning);
* `jwks::Error` carried `Io`, `Json` and `Base64` variants nothing in the
module converts into -- `Io`/`Json` served the notary's server side,
`Base64` never existed there. The type now names exactly the sources
the module converts: Jwks, Tlsn, Transcript, Crypto, Http;
* three manifest comments still described a `notary` dependency: the
rust-version floor, the publish = false rationale, and the libid-rs pin
block (which also narrated a branch rev now replaced by the tag). The
tlsn-patch comment likewise; and a stray blank line where the notary
block was;
* the e2e doc and the module doc still spoke from the notary's point of
view;
* the mock's hyper test uses `tokio::io::duplex`/`AsyncReadExt`, which
compiled only through feature unification -- declare `io-util`.
Assisted-by: Claude Fable 5.1
Signed-off-by: xgreenx <xgreenx9999@gmail.com>
xgreenx
marked this pull request as ready for review
September 14, 2026 11:23
ae8d1c5 replaced a single line of a multi-line comment and left its neighbour dangling mid-sentence. Rewrite the block under the tlsn `[patch]` header as one paragraph. Comment only. Assisted-by: Claude Fable 5.1 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
… example `examples/notarize_jwks` was a one-off from 2026-09-03: it captured a real notarized reading so libid-contracts#21 could test `GoogleJwtRoots` against a record Google actually served. It came along with the prover helpers when they moved here, but it is not keeper functionality -- the keeper's own `proof.rs` -> `notarize_jwks` -> `rotate` path is that flow with the chain step on the end. Replace it with the test that flow deserves. `e2e.rs` proves everything but MPC-TLS, with the mock as the proof source; `tests/e2e_real.rs` proves the rest: a running notary the keeper shares no crate with, the real contracts on Anvil, Google's live key set, and one genuine MPC-TLS rotation -- dry run, the rotation with the fee landing in the service, steady state. It is `#[ignore]`d because it needs a notary (`KEEPER_E2E_NOTARY`, local binary or the ghcr.io image) and network to Google; the module docs say how to run it. `KEEPER_E2E_CAPTURE` writes the record it obtained, which is what the example used to do, with the signature checked against the trusted address first. `chrono` leaves the dev-dependencies with the example. Assisted-by: Claude Fable 5.1 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
`cargo test --all` covers everything but MPC-TLS, with the mock prover standing in. The ignored e2e covers the rest, and nothing ran it. The notary is built from source at a pinned rev rather than pulled. The published image predates the ceremony-attestation TCP path this test drives. Bump NOTARY_REV once an image carries it. The job reaches www.googleapis.com on purpose. GoogleJwtRoots pins that authority, so a local TLS fixture cannot stand in. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
Latest of both. libid-rs v0.4.0 brings libid-profiles and libid-identity 0.10 and two transcript fixes the JWKS layout depends on: a JSON member is found with the whitespace JSON allows, and one scan finds the key for both member shapes. libid-contracts 0.10.0 is the version the ceremony contracts ship in. The anvil rotation e2e deploys NotaryService and GoogleJwtRoots from its artifacts and still reaches steady state. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
reqwest 0.13 is the version alloy's HTTP transport already pulls, so the build now carries one reqwest and one TLS stack instead of two; `rustls` is that release's name for the `rustls-tls` backend. toml 1, base64 0.23 and num-bigint 0.5 are the current majors, and nothing here exchanges their types with another crate. alloy and k256 stay: libid-contracts hands back alloy 1 types and libid-crypto takes a k256 0.13 key, so a newer major would be a second, incompatible type rather than an upgrade. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
1.98.1 is the current stable. The pin sits above the crate's inherited 1.95 floor, which no job exercises -- so say that, rather than repeating a claim about building on the floor that stopped being true at 1.97. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
CI no longer deploys the contracts from inside this test: libid-deploy puts them on the chain, so the addresses have to come in from outside. KEEPER_E2E_GOOGLE_JWT_ROOTS selects that stack, KEEPER_E2E_RPC names its chain, KEEPER_E2E_NOTARY_SERVICE overrides the service the fee is paid to -- and with none of them set the test still spawns its own anvil and deploys, so a local run stays one command. The fee now comes from quoteRotation() rather than the constant, and two wirings an external stack can get wrong are asserted before the session. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
The job built the notary from source and deployed the contracts from inside the test, so it proved the rotation against two things no deployment ever runs. It now pulls the published notary image and lays the stack down with libid-deploy on a throwaway anvil, which is exactly what a deployment does; the image, the tool and its network file are one env var each at the top of the file. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
The graph has no openssl-sys -- ldd on the binary lists libc, libm and libgcc_s -- so libssl-dev and libssl3 were claiming a dependency that does not exist. The keeper writes nothing and listens on nothing, so it runs as uid 10001. KEEPER_CONFIG now points at /etc/keeper/keeper.toml, because --config defaults to a relative path that resolves against / in a container, which makes a mounted config the whole run recipe. The OCI labels link the ghcr package to this repo, as the notary's do. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
A release candidate could not be published at all, and every release moved :latest, so pulling it could land on an RC. Both now follow the notary's rules, which downstream consumers already read. The header also described a wasm bundle this repo does not ship. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
The head of the notary's release branch, and the tag its own image workflow published last. A `custom-` tag is a build artefact: this becomes a version tag once notary#10 merges and a release is cut. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
The notary pull is the slowest step and depends on nothing else in the job, so running it first both overlaps the download with the deploy and proves the image starts even on a run that fails further down. Assisted-by: Claude Opus 5 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
The step looked only under [identity]. chain-configurations declares the ceremony contracts under [contracts], so the lookup found nothing and the job failed after a successful deploy. Read both sections. The pre-0.10 schema carried the roots under [identity] as identity_jwks_roots, and the new one is still settling upstream, so accepting either keeps this from breaking on a rename. Assisted-by: Claude Fable 5.1 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
custom-1f54c19 was amd64 only, so the job worked on GitHub runners but forced emulation for anyone running it on an arm64 machine. custom-c957999 is a manifest list covering linux/amd64 and linux/arm64. Verified: the arm64 variant runs natively here and the rotation passes against it. Assisted-by: Claude Fable 5.1 Signed-off-by: xgreenx <xgreenx9999@gmail.com>
This was referenced Sep 14, 2026
Contributor
Author
|
Superseded by #9, which is now a single PR against |
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.
The keeper reached its notarized reading through the notary crate, and CI proved the rotation against a source-built notary and inline-deployed contracts.
Changes
src/jwks/holds the JWKS layout, the prover overlibid_tlsn::prover_genericand the mock; thenotarydependency is gone.v0.4.0, libid-contracts0.10.0, TLSNotary550220e, the 24-entry libid-org/mpz patch4db9454.ghcr.io/libid-org/notary:custom-1f54c19and deploys withlibid-deployonto a throwaway anvil — image, tool and network file one env var each.tests/e2e_real.rstakesKEEPER_E2E_GOOGLE_JWT_ROOTS,KEEPER_E2E_RPCandKEEPER_E2E_NOTARY_SERVICE; with none set it spawns its own anvil, so a local run stays one command.KEEPER_CONFIGto/etc/keeper/keeper.toml; releases publish RC tags,:latestonly for final.Verified
cargo test --all: 27 unit, 4 integration; clippy-D warningsand nightly fmt clean on 1.98.1.keeper statusreads the chain from a mounted config.Not verified / known issues
libid-deployv0.7.0 andnetworks/local-dev.tomldo not exist yet: both URLs and the[identity]key name are guesses until that release lands.