oc · docs
docs / federation custody

OC Me · Federation custody

Status: this is the design, not today. No federation is bound. /api/federations is the machine-readable answer and it currently serves a single entry with no invite, so no client can join one. During bring-up OrangeCheck holds every user's accrued balance and is the party that moves it. That is a stage, deliberately: OrangeCheck operates every role until independent operators take them. Read the descriptor schema, graduation envelope and rotation rules below as the contract that comes into force when a federation binds, and me.ochk.io/custody as the present tense.

me.ochk.io is designed to be federation-custodied by default, with a self-custody graduation flow on demand. This page is the user-facing explanation; the protocol-level contract is at oc-attest-protocol/FEDERATION-CUSTODY.md (v1.2-draft-1, additive extension).

Two questions get conflated here, and this page used to conflate them. Self-custody of your signing key is live and real on the BIP-322 path — that key never reaches OC. Self-custody of your sats is not live for anyone. The rest of this page is about the second one. The in-tree audit at NON_CUSTODIAL_AUDIT.md walks the gap with file paths.

What "federation-custodied" will mean

Once a federation is bound, your me.ochk.io identity is backed by a Bitcoin address (BIP-322 path) or a federation-issued ecash note set (email-OTP path). For the federation path, the private key that controls the underlying on-chain UTXOs is held collectively by an M-of-N guardian set — no single guardian (and not OC the company) can spend or freeze. Recovery is by re-proving your email, not by remembering twelve words. The guardians threshold-sign on your behalf when you sign in; you don't see it and never need to.

None of that is in force. The guardians that once ran this were torn down in July 2026, and the browser-side Fedimint client that would have joined a federation was removed from oc-me-web in September 2026 — it could only ever reach its own error path.

The three options at threshold

signing_methodhow it workslive today?
federation custody (the destination)fedimint_thresholdguardians collectively hold the key. recovery by re-proving email.no. no federation is bound, so no client can join one — /api/federations publishes that state.
fedimint clientfedimint_threshold (different federation)sweep to a fedimint federation you trust more (your community's, your country's, your own).opens once (1) binds; depends on the graduation envelope.
self-custodybip-322sweep to any BIP-322-capable Bitcoin wallet (UniSat, Xverse, Leather, Alby, Sparrow, hardware wallet). only you can sign.sign-in is live (in-place, no redirect) and the signing key is yours. the sat sweep is not — there is no federation balance to sweep.

The protocol accommodates the round-trip back to federation custody via attestation re-issuance under the new custody descriptor.

Graduation envelope

Per the v1.2-draft-1 oc-attest extension, graduation publishes an envelope carrying both an M-of-N guardian quorum sig (federation releases custody) and a self-key sig (you prove you hold the key now). The envelope is anchored to a bitcoin block via OpenTimestamps so any verifier can confirm graduation happened at a specific time.

{
    "v": 1,
    "kind": "orangecheck-graduation",
    "address": "bc1q...",
    "from_federation": "fed:abc123…",
    "to": "single-key",
    "graduated_at": "2026-04-30T20:00:00Z",
    "proof": [
        { "address": "bc1qg1…", "sig": "..." },
        { "address": "bc1qg2…", "sig": "..." },
        { "address": "bc1qg3…", "sig": "..." },
        { "address": "bc1q...", "sig": "...", "kind": "self-key" }
    ]
}
FieldRule
from_federationContent hash of the federation custody descriptor releasing the address.
to"single-key" (graduating to BIP-322) or "federation" (re-binding to a new descriptor).
proofM signatures from M of N declared guardians PLUS one self-key signature.
graduated_atISO-8601 timestamp; the OTS proof anchors this to a Bitcoin block.

The envelope contract is finalized at the spec level and reflected in the /me/graduate UI, which states today what it can and cannot do. The producing path — collecting a quorum signature from a real federation — opens when a federation binds.

Guardian descriptor

A federation custody descriptor is a content-addressed canonical JSON object — same shape as oc-agent-protocol's federation principal, re-purposed for custody:

{
    "v": 1,
    "kind": "attest-federation-custody",
    "address": "bc1q…",
    "threshold": "3-of-5",
    "guardians": [
        { "address": "bc1qg1…", "alg": "bip322", "name": "alice" },
        { "address": "bc1qg2…", "alg": "bip322", "name": "bob" },
        { "address": "bc1qg3…", "alg": "bip322", "name": "carol" },
        { "address": "bc1qg4…", "alg": "bip322", "name": "dave" },
        { "address": "bc1qg5…", "alg": "bip322", "name": "erin" }
    ],
    "implementation": {
        "kind": "fedimint",
        "federation_id": "fed11qgqzcq…",
        "version": "0.4"
    }
}

The descriptor id is fed: + lowercase hex SHA-256(canonical_descriptor_bytes).

What stays the same when you graduate

Stays the sameChanges
Your bitcoin address (the canonical identifier)The signing method (fedimint_thresholdbip-322)
Your attest tier (anonymous / bonded / kyc-light / kyc-strong)Who holds the private key (you, instead of the federation)
Your /me/earn history, connected sites, agent delegationsHow recovery works (you own backup; lose the key, lose the funds)
Your sat-earning rateThe shape of signing_method in attestation envelopes

Guardian rotation

Guardian rotation produces a new descriptor with a new id. Old attestations remain verifiable against the old descriptor; new attestations bind to the new descriptor. Rotation envelopes are authenticated by M-of-N signatures from the old descriptor and OTS-anchored so any verifier can resolve the active descriptor at any historical instant.

Reading further