Skip to main content

Module project_identity

Module project_identity 

Source
Expand description

Project identity: the project key, its certificate and the revocation view (ADR-103 A6/A7, Phase 2 package C).

One project key (<root>/.weftos/project.key) is the node key, the chain signing key, the anchor key and the proof-of-possession key. It therefore never signs bare bytes: every signature it makes carries a distinct domain tag defined next to the statement it signs (clawft_types::project::cert): weftos-project-anchor-v1 for anchors and weftos-mesh-local-pop-v2 for proof of possession (this module’s pop_sign, which also signs the operation and the user key id). The user key signs certificates under weftos-project-cert-v1. Chain events keep their own canonical form.

§Trust on first use (TOFU), honestly

The first key presented for a project id is certified; a different key for the same id is refused until an explicit Admin project.rekey. Nothing here can tell whether the first registrant really is the project: the only guards for first registration are the one-shot spawn nonce the user daemon handed to the child it started and the binding to the project’s manifest (the owner’s registration act). A same-uid process that learns the nonce first wins the id. Phase 3 peer credentials narrow this; they do not remove it.

§Revocation and crash safety

RevocationView::build merges three sources: the user chain’s project.register|rekey|revoke events (source SOURCE, reserved: see is_reserved_source), the append-only identity journal (IdentityJournal), and the certificate files. The chain is saved only on clean shutdown, so the journal (fsynced before every chain append) is what keeps bindings and revocations across a crash. Every certificate is re-verified against the user key while folding. The merge is a union: the bound key of a project is its highest-serial certificate whose key is not revoked, so source order cannot resurrect a revoked key.

Expired certificates still count as bound: an expired cert keeps its id (and its key) until it is rekeyed or revoked. This is moot while expires_at is null (Phase 2); the phase that sets expiry must decide whether an expired binding should free the id.

Re-exports§

pub use crate::user_key_rotation::KIND_ROTATED;
pub use crate::user_key_rotation::ROTATION_FILE;
pub use crate::user_key_rotation::RotationError;
pub use crate::user_key_rotation::RotationLog;
pub use crate::user_key_rotation::RotationRecord;
pub use crate::user_key_rotation::UserKeyHistory;
pub use crate::chain_anchor::ANCHOR_SOURCE;
pub use crate::chain::KERNEL_SOURCES;
pub use crate::chain::RESERVED_SOURCES;
pub use crate::chain::is_caller_reserved_source;
pub use crate::chain::is_reserved_source;

Structs§

IdentityJournal
The journal in a manifests directory.
JournalLock
Exclusive lock over the journal for a read-modify-write. Held until dropped. flock locks the open file, so two threads of one process exclude each other as well as two processes. Appending needs one.
RevocationView
Which keys of which projects are certified or revoked, merged from the user chain, the identity journal and the certificate files. Built only by Self::build; there is no way to add an unverified certificate.
SharedLock
A shared (read) lock; held while a view is built.

Enums§

IdentityError
Why an identity operation was refused.
JournalRecord
One journal line.
Registration
Outcome of RevocationView::plan_registration.

Constants§

JOURNAL_FILE
Journal file name.
KIND_REGISTER
A project key was certified.
KIND_REKEY
A project key was replaced.
KIND_REVOKE
A project key was revoked.
SOURCE
Chain event source of the project identity events (user chain).

Functions§

hex
Lowercase hex of bytes (re-export for callers building payloads).
load_or_create_project_key
Load the project key at path, or create it (mode 0600, raw 32-byte seed: the format of ChainManager::load_or_create_key).
parse_pubkey
Decode a 32-byte lowercase-hex public key.
pop_sign
Prove possession of the project key: sign weftos-mesh-local-pop-v2\n<op>\n<user_key_id>\n<nonce>\n<project_id>. The parts are validated first; the nonce must be one the user daemon issued (single use), which this function cannot check.
pop_verify
Verify a proof of possession by project_pubkey.
project_chain_key
The chain signing key of a project kernel: the project key pre_boot already loaded and certified (seed, the node key seed), confirmed against the 0600 project.key at path with the strict reader (no symlink, no creation, no chmod). A missing seed, a missing file or a file that no longer holds that key refuses the boot (ADR-103 A7, one key).
sign_cert
Certify req with the user key. Deterministic. Refuses an invalid project id and an expiry that is not after the issue time.
verify_cert
Verify cert against the user key the caller trusts, at the current time: signature, both key ids recomputed from their public keys, issuer, expires_at. Revocation is a separate check (RevocationView::check_cert).
verify_cert_at
verify_cert against an explicit now.
verify_cert_historic
Check that cert is well-formed and was sealed by a user key trust accepts for the certificate’s issued_at: the current key always, a retired key only up to its rotation point (ADR-103 A13). Expiry and the future-skew rule are ignored, as in verify_signature_only.
verify_signature_only
Check only that cert is well-formed and signed by trusted_user_pubkey, ignoring expiry and the future-skew rule (judged at its own issue time). Used when folding history: an expired certificate still occupies its id.
write_private_atomic
Write bytes to path via a temp file in the same directory and an atomic rename, mode 0600 from creation (never briefly wider).