Mode 4 — Keyless Threshold
Confium’s existing four deployment modes all share one characteristic: the threshold keyset is persistent. Shares are generated once, distributed to N custodians, and used for every signing ceremony until rotated. That’s the right model for high-stakes long-lived keys.
But for many real-world signing workflows — CI/CD release pipelines, package publishing, daily document signing — persistent threshold keys are operational overkill. Share management, rotation, auditing, and storage dominate the cost.
Mode 4 (Keyless Threshold) combines Confium’s threshold signing with the Sigstore keyless pattern:
| Property | Source |
|---|---|
| Threshold signing (T-of-N) | Confium |
| OIDC identity verification | Sigstore pattern |
| Short-lived ceremony-bound certs | Fulcio pattern |
| Transparency-log anchoring | Rekor pattern (= log.confium.org) |
The result: threshold signatures with zero persistent keys.
When to use Mode 4
Use Mode 4 when:
- No single party should sign alone, but no one wants to operate persistent share storage.
- Signer identity is the trust anchor, not a long-lived key (“this release was signed by 3-of-5 directors”, not “signed by key 0xABC”).
- Per-ceremony auditability is sufficient; you don’t need to re-sign future artifacts with the same key.
- CI/CD release pipelines want threshold guarantees without long-lived HSM-managed keys.
Don’t use Mode 4 when:
- Long-term archival is required (the OIDC-issued cert expires in ~10 minutes; signatures remain valid but the cert path doesn’t). Use Mode 3 (Sovereign PKI) instead.
- Regulatory key escrow is required (you need to re-sign with the same key years from now).
- The same key must sign many artifacts over a long period (use Mode 2 — PKI Drop-in).
How it works
OIDC token from
GitHub Actions / Google / Okta
│
┌──────────────────────────┼──────────────────────────┐
│ ┌───────────────────────▼───────────────────────┐ │
│ │ Signer 1: ephemeral keypair + OIDC identity │ │
│ └───────────────────────┬───────────────────────┘ │
│ ┌───────────────────────▼───────────────────────┐ │
│ │ Signer 2: ephemeral keypair + OIDC identity │ │
│ └───────────────────────┬───────────────────────┘ │
│ ┌───────────────────────▼───────────────────────┐ │
│ │ Signer 3: ephemeral keypair + OIDC identity │ │
│ └───────────────────────┬───────────────────────┘ │
│ │ │
│ ┌─────────────▼─────────────┐ │
│ │ Coordinator (Confium) │ │
│ │ ───────────────────────── │ │
│ │ 1. verify each OIDC token │ │
│ │ 2. ephemeral DKG │ │
│ │ → joint ephemeral key │ │
│ │ 3. Fulcio issues cert │ │
│ │ binding OIDC identities│ │
│ │ to joint key │ │
│ │ 4. T-of-N threshold sign │ │
│ │ 5. anchor in log.confium │ │
│ │ 6. destroy ephemeral keys │ │
│ └───────────────────────────┘ │
└─────────────────────────────────────────────────────┘
What the verifier sees
Nothing changes on the verifier side. The verifier still sees:
- One signature (64-byte
(r, s)ECDSA-P256). - One public key (33-byte SEC1 compressed P-256 point).
- One certificate (the Fulcio-issued short-lived cert that binds the OIDC identities to the joint public key).
The signature verifies under the public key in the normal way
(OpenSSL, node:crypto, Go’s crypto/ecdsa, etc.). What’s
different is where the public key came from: a per-ceremony
threshold DKG, not a long-lived HSM.
Components
| Crate | Role |
|---|---|
confium-oidc |
OIDC token verifier for any standards-compliant issuer (GitHub Actions, Google, Okta, Azure AD, Auth0, etc.) |
confium-tc-cmp20 (or other TC crate) |
The threshold protocol that runs across the OIDC-verified signers |
confium-log-server |
The log.confium.org reference transparency log server (RFC 6962) |
confium-log-monitor |
Third-party monitor that watches the log and detects fork attempts |
confium-log-edge |
Pure-edge deployment of the log server on Cloudflare Workers + D1 |
Quickstart
use confium_oidc::{OidcVerifier, OidcIssuer};
let verifier = OidcVerifier::new();
let issuer = OidcIssuer::GitHubActions;
let claims = verifier.verify(&issuer, "eyJhbGciOi...")
.expect("OIDC token verifies");
println!("{} ({})", claims.subject, claims.email.unwrap_or_default());
Combined with confium-tc-cmp20 + a Fulcio-style CA, this
powers keyless threshold signing ceremonies. Each signer
authenticates via OIDC and contributes to the joint ephemeral
threshold key.
Mode 4 vs the other modes
| Property | Mode 1 | Mode 2 | Mode 3 | Mode 4 |
|---|---|---|---|---|
| Threshold signing | ✓ | ✓ | ✓ | ✓ |
| Persistent shares | ✓ | ✓ | ✓ | ✗ (ephemeral) |
| Identity-bound | ✗ | ✗ | ✓ | ✓ (OIDC) |
| Standards adapters (PKCS#11, OpenSSL, JCE) | ✗ | ✓ | varies | ✗ |
| Long-term archival | n/a | varies | ✓ | ✗ (cert expires) |
| Operational overhead | low | medium | high | very low |
Mode 4 is the right answer when you want the cryptographic guarantees of threshold signing without the operational burden of key management.
See also
- Keyless threshold code signing — the canonical Mode 4 use case.
- Deployment modes — Modes 1–3.
- Confium + RNP — sibling project for standard OpenPGP.
- Architecture — the engine + coordinator
- adapter stack.