Skip to content

feat: CryptoOfficer role with optional split-key ceremony - #991

Open
Manuthor wants to merge 3 commits into
issue_983_user_idfrom
feat/split_key
Open

feat: CryptoOfficer role with optional split-key ceremony#991
Manuthor wants to merge 3 commits into
issue_983_user_idfrom
feat/split_key

Conversation

@Manuthor

@Manuthor Manuthor commented Jun 8, 2026

Copy link
Copy Markdown
Contributor

No description provided.

@Manuthor Manuthor changed the title feat: add super-admin role under split-key ceremony feat: add admin role under split-key ceremony Jun 11, 2026
@Manuthor
Manuthor requested a review from Copilot June 11, 2026 18:53

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR introduces a 3-role RBAC model (Operator / Crypto Officer / Administrator) and adds split-key (Shamir/XOR) KMIP operations to support an “Administrator key ceremony” activation flow, alongside broad documentation updates.

Changes:

  • Add server-level RBAC configuration (operator/crypto officer/admin) and enforce role permissions during KMIP dispatch.
  • Implement KMIP 2.1 CreateSplitKey / JoinSplitKey operations plus DB persistence for Administrator ceremony activation and runtime disable/status endpoints.
  • Extend test infrastructure and vectors to cover Administrator behavior and split-key round-trips.

Reviewed changes

Copilot reviewed 64 out of 65 changed files in this pull request and generated 13 comments.

Show a summary per file
File Description
pkg/kms.toml Updates sample config comments for new RBAC keys (operator/crypto officer/administrator).
documentation/mkdocs.yml Adds nav entry for the new key ceremony documentation page.
documentation/docs/configuration/server_configuration_file.md Updates server config reference comments for RBAC keys.
documentation/docs/configuration/authorization/key_ceremony.md New detailed documentation page for Administrator split-key ceremony flow.
documentation/docs/configuration/authorization.md Updates authorization docs (RBAC + additional role documentation).
documentation/docs/certifications_and_compliance/audit/owasp_security_audit.md Updates audit doc references from privileged_users to crypto_officer_users.
documentation/docs/certifications_and_compliance/audit/multi_framework_security_audit.md Same terminology update for audit/compliance mapping.
deny.toml Adds ignored advisory entry for an unmaintained transitive dependency.
crate/test_kms_server/src/vector_runner.rs Adds vector-runner support for administrator REST steps and capturing repeated TTLV tags.
crate/test_kms_server/src/test_server.rs Renames privileged-users test server helpers to crypto-officer equivalents; switches to PEM to avoid macOS PKCS#12 concurrency issues.
crate/test_kms_server/src/lib.rs Re-exports renamed test server helpers.
crate/test_kms_server/README.md Documents new Administrator and split-key vectors.
crate/server/src/tests/test_utils.rs Injects RoleConfig into test Actix app state instead of privileged_users.
crate/server/src/start_kms_server.rs Wires RoleConfig into server scope state; adds Administrator status/disable endpoints.
crate/server/src/routes/access.rs Updates access routes to use RoleConfig; adds Administrator status/disable handlers.
crate/server/src/main.rs Updates ClapConfig test initializer for new RBAC fields.
crate/server/src/core/retrieve_object_utils.rs Adds Administrator bypass to per-object permission checks.
crate/server/src/core/operations/rekey.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/operations/rekey_keypair.rs Same renaming for ReKeyKeyPair path.
crate/server/src/core/operations/register.rs Same renaming for Register path.
crate/server/src/core/operations/mod.rs Registers new split-key operation handlers.
crate/server/src/core/operations/message.rs Adds split-key ops to KMIP message processing; refactors futures pinning.
crate/server/src/core/operations/locate.rs Adds Administrator Locate bypass path using DB find_all().
crate/server/src/core/operations/join_split_key.rs Implements JoinSplitKey operation and Administrator ceremony activation hook.
crate/server/src/core/operations/import.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/operations/dispatch.rs Adds RBAC gate at dispatch time; routes new split-key operations.
crate/server/src/core/operations/create.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/operations/create_split_key.rs Implements CreateSplitKey operation and ceremony tagging.
crate/server/src/core/operations/create_key_pair.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/operations/certify/resolve_subject.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/operations/certify/certify_op.rs Same renaming and pinning update.
crate/server/src/core/kms/permissions.rs Renames privileged user parameter; introduces KMS::is_administrator() runtime check.
crate/server/src/core/kms/other_kms_methods.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/kms/kmip.rs Adds KMS wrappers for split-key ops; refactors pinning and renames privileged user plumbing.
crate/server/src/core/cover_crypt/rekey_keys.rs Renames privileged user parameter to crypto officer users.
crate/server/src/core/cover_crypt/create_user_decryption_key.rs Same renaming for Covercrypt USK creation flow.
crate/server/src/config/wizard/mod.rs Wizard now captures RBAC lists (operator/crypto officer/admin).
crate/server/src/config/wizard/advanced_wizard.rs Implements wizard prompts for new RBAC keys.
crate/server/src/config/params/server_params.rs Replaces privileged_users with role_config: RoleConfig and validates role separation.
crate/server/src/config/command_line/super_admin_config.rs Adds a SuperAdminConfig type (currently appears unused).
crate/server/src/config/command_line/clap_config.rs Adds new CLI config fields for RBAC and admin ceremony parameters; updates Debug output.
crate/server/Cargo.toml Adds crypto crate dependency and rand dependencies; extends non-fips features.
crate/server_database/src/stores/sql/sqlite.rs Adds administrator_activations table init; implements find_all() and activation persistence methods.
crate/server_database/src/stores/sql/query.sql Adds SQL schema + queries for administrator activations.
crate/server_database/src/stores/sql/query_mysql.sql Adds MySQL schema + queries for administrator activations.
crate/server_database/src/stores/sql/pgsql.rs Adds find_all() and administrator activation persistence for Postgres.
crate/server_database/src/stores/sql/mysql.rs Adds find_all() and administrator activation persistence for MySQL.
crate/server_database/src/stores/sql/locate_query.rs Adds query_all_from_attributes() for admin locate.
crate/server_database/src/stores/redis/redis_with_findex.rs Adds find_all() behavior for Redis-findex; stubs/blocks ceremony persistence.
crate/server_database/src/core/database_permissions.rs Exposes administrator activation APIs on Database.
crate/server_database/src/core/database_objects.rs Adds Database::find_all() aggregator.
crate/kmip/src/kmip_2_1/kmip_operations.rs Adds KMIP operation structs/enums for CreateSplitKey/JoinSplitKey.
crate/kmip/src/kmip_2_1/kmip_messages.rs Adds (de)serialization support for CreateSplitKey/JoinSplitKey operations.
crate/interfaces/src/stores/permissions_store.rs Extends PermissionsStore trait for admin ceremony persistence.
crate/interfaces/src/stores/objects_store.rs Extends ObjectsStore trait with find_all() for admin locate.
crate/interfaces/src/hsm/hsm_store.rs Implements find_all() for HSM store via admin-owner find().
crate/crypto/src/crypto/split_key/mod.rs New split-key cryptographic primitives (SSS over GF(2^8) + XOR) with tests.
crate/crypto/src/crypto/mod.rs Exposes new split_key module.
crate/crypto/Cargo.toml Adds rand_core dependency.
crate/clients/ckms/src/tests/security/privilege_bypass.rs Updates tests for crypto_officer_users naming.
crate/clients/ckms/src/tests/access.rs Renames privileged-users test to crypto-officer variant.
crate/access/src/access.rs Introduces Role/RoleConfig/AdministratorConfig and role validation logic.
CHANGELOG/feat_split_key.md Adds branch changelog for the feature (contains “super-admin” naming claims).
Cargo.lock Updates lockfile for new dependencies (crypto + rand_core).

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread crate/server/src/core/retrieve_object_utils.rs Outdated
Comment thread crate/access/src/access.rs Outdated
Comment thread crate/server/src/core/operations/dispatch.rs
Comment thread crate/server/src/core/operations/join_split_key.rs
Comment thread crate/server/src/core/operations/join_split_key.rs
Comment thread crate/interfaces/src/stores/permissions_store.rs Outdated
Comment thread crate/server/src/routes/access.rs
Comment thread documentation/docs/configuration/authorization.md Outdated
Comment thread crate/server/src/config/command_line/super_admin_config.rs Outdated
Comment thread CHANGELOG/feat_split_key.md
Manuthor added a commit that referenced this pull request Jun 11, 2026
- dispatch: make check_role_permission async; remove dispatch-level blocking
  for KmipOperation-mapped ops (handlers enforce crypto_officer_users + explicit
  grants); LIFECYCLE_OPERATION_TAGS now allow through if user has explicit Create
  grant in DB -- fixes regression in test_crypto_officer_users
- access: role_for() only returns Administrator when require_ceremony=false;
  ceremony candidates are not elevated at dispatch before ceremony completes
- retrieve_object_utils: Administrator bypass limited to non-HSM objects
- join_split_key: add split_key_method validation; add crypto_officer check
  before database.create(); fix doc comment wording
- database_objects: find_all() propagates errors instead of swallowing
- locate_query: rewrite query_all_from_attributes with full attribute filters
- permissions_store: update revoke_administrator_activation doc contract
- routes/access: fix config key reference in error msg (administrator_users)
- documentation: replace Super-admin section with correct Administrator role docs
- remove dead super_admin_config.rs file
- CHANGELOG: fix log names and claims about rename completion
@Manuthor Manuthor changed the title feat: add admin role under split-key ceremony feat: add admin and auditor roles under split-key ceremony Jun 12, 2026
Manuthor added a commit that referenced this pull request Jun 14, 2026
- dispatch: make check_role_permission async; remove dispatch-level blocking
  for KmipOperation-mapped ops (handlers enforce crypto_officer_users + explicit
  grants); LIFECYCLE_OPERATION_TAGS now allow through if user has explicit Create
  grant in DB -- fixes regression in test_crypto_officer_users
- access: role_for() only returns Administrator when require_ceremony=false;
  ceremony candidates are not elevated at dispatch before ceremony completes
- retrieve_object_utils: Administrator bypass limited to non-HSM objects
- join_split_key: add split_key_method validation; add crypto_officer check
  before database.create(); fix doc comment wording
- database_objects: find_all() propagates errors instead of swallowing
- locate_query: rewrite query_all_from_attributes with full attribute filters
- permissions_store: update revoke_administrator_activation doc contract
- routes/access: fix config key reference in error msg (administrator_users)
- documentation: replace Super-admin section with correct Administrator role docs
- remove dead super_admin_config.rs file
- CHANGELOG: fix log names and claims about rename completion
@Manuthor Manuthor changed the title feat: add admin and auditor roles under split-key ceremony feat: CryptoOfficer role with optional split-key ceremony Jun 18, 2026
@Manuthor
Manuthor force-pushed the feat/split_key branch 2 times, most recently from 4bc2812 to a1acabf Compare June 19, 2026 21:51
@Manuthor
Manuthor force-pushed the feat/split_key branch 7 times, most recently from f7251de to 13bcf0f Compare July 9, 2026 21:53
@serene-kitfisto-8899

Copy link
Copy Markdown
Contributor

Split Knowledge Ceremony — Comparative Analysis

1. Zcash Trusted Setup Ceremony (2016)

The IEEE Spectrum article documents the Zcash ceremony where 6 geographically distributed stations each generated a fragment of a "toxic waste" secret using multi-party computation (MPC). The full secret never existed in any single location — it was a round-robin protocol where each station contributed without seeing others' input. After completion, all compute nodes were physically destroyed.

Can this PR replicate a Zcash-style ceremony? No — different problem, different architecture:

Aspect Zcash Cosmian KMS (this PR)
Purpose Generate zk-SNARK parameters while destroying toxic waste Activate CryptoOfficer role (RBAC elevation)
Scheme Multi-party computation (MPC) — fragments never combined XOR n-of-n — all shares recombined on server
Where shares live Air-gapped machines in different cities KMIP SplitKey objects in the KMS database
Trust model Distributed — no single point ever holds full secret Centralized — server sees reconstructed secret during JoinSplitKey
Destruction Irrecoverable physical destruction of all nodes Reconstructed key persists as new managed object

The KMS solves split knowledge for role activation (nuclear launch key model), not a trusted setup ceremony.


2. Thales Luna HSM — The Industry Precedent

The Thales Luna HSM (FIPS 140-3 Level 3) is the closest real-world equivalent. It uses the same XOR n-of-n scheme for Security Officer activation via physical PED keys.

Dimension Thales Luna HSM Cosmian KMS (this PR)
Scheme XOR n-of-n (all shares required) XOR n-of-n (all shares required)
Role activated Security Officer / Crypto Officer CryptoOfficer
Share medium Physical PED keys (USB tokens) KMIP SplitKey objects in database
Authentication boundary Dedicated PED hardware — secrets never touch a PC KMS server RAM during JoinSplitKey
True M-of-N ❌ Despite marketing, it's XOR N-of-N ❌ Same — threshold must equal total_parts
Physical security FIPS 140-3 Level 3 tamper-evident hardware Software-only (server process)
Ceremony initiation lunash:> hsm init with PED prompts CreateSplitKey KMIP operation
Reconstruction PED collects shares sequentially at HSM JoinSplitKey collects all share UIDs in one request
Share distribution Manual — each custodian receives a physical token Via KMS permissions — different users own different share objects
Activation persistence Volatile — reboot requires re-auth DB-persisted activation record (survives restarts)
Deactivation HSM deactivation command or reboot REST POST /access/crypto_officer/disable
Audit trail HSM-internal audit log Structured log + SHA-256 fingerprint of reconstructed secret
Loss tolerance Zero — lose one PED key = irrecoverable Zero — all shares must be joined
Ceremony secret protection Hardware enclave (never exportable) AES-256-GCM encrypted ceremony record

Where this PR matches Luna

  • ✅ Same cryptographic primitive (XOR n-of-n, information-theoretically secure)
  • ✅ Same FIPS rationale (NIST SP 800-57 Part 2 §4.6, FIPS 140-3 §7.4)
  • ✅ Same role semantics (officer role dormant until ceremony completes)
  • ✅ Same all-or-nothing property (no redundancy)

Where this PR improves over Luna

  • 🟢 No proprietary hardware — works on commodity servers
  • 🟢 KMIP-native — standard CreateSplitKey/JoinSplitKey operations (interoperable)
  • 🟢 Persistent activation — role survives reboots (Luna requires re-auth after power cycle)
  • 🟢 Programmable — REST API + CLI + Web UI for ceremony management
  • 🟢 Richer audit — SHA-256 fingerprint, participant list, DB record

Where Luna is stronger

  • 🔴 Hardware isolation — shares live on tamper-evident tokens, never in server memory
  • 🔴 Air-gap guarantee — PED is physically separate, no network attack surface
  • 🔴 FIPS Level 3 certification — tamper-resistance validated by NIST lab
  • 🔴 No software trust — HSM firmware enforces policy; here the server code must be trusted

Summary

This PR is architecturally the software equivalent of the Thales Luna PED ceremony — same XOR scheme, same n-of-n semantics, same FIPS rationale — trading hardware tamper-resistance for programmability, interoperability, and persistence. The main trust difference: in Luna, the secret never leaves the HSM; here, the server process momentarily holds the reconstructed secret in RAM during JoinSplitKey.

@serene-kitfisto-8899

Copy link
Copy Markdown
Contributor

ADR: Multi-Domain Split-Key Ceremony Architecture — 40 Architectural Decision Points

Full ADR committed: documentation/docs/adr/2026-07-24-multi-domain-split-key-ceremony.md

Design Principles

  • All state in DB (not config files) — HA-safe, no restart during ceremony
  • Multi-domain with independent ceremony lifecycles (Luna HSM partition model)
  • Progressive share submission — true split knowledge, no single user sees all shares

Domain Model

# Decision
ADP-1 Domain = independent partition with own ceremony lifecycle (Luna HSM model)
ADP-2 Domains created via explicit REST API + DB table
ADP-9 Auto-create "default" domain at DB init for backward compatibility
ADP-13 domain_id nullable FK column on objects table (NULL = default domain)

User/Role Assignment

# Decision
ADP-3 CO candidates assigned per-domain in DB (domain_users table)
ADP-14 Only CO candidates for a domain can initiate its ceremony
ADP-15 Ceremony activates the DOMAIN — all CO candidates gain the role together
ADP-19 Custodians (share holders) ≠ CO candidates — any domain user can be custodian
ADP-31 Users with Create permission can create domains; creator = first CO candidate

Ceremony Lifecycle

# Decision
ADP-4 DB state machine: Inactive → SplitKeysIssued → Activated → Disabled
ADP-5 Optimistic concurrency (version + CAS) for HA race prevention
ADP-7 Instances read ceremony state from DB per-request (no restart, no cache)
ADP-12 No automatic expiry — pending ceremonies live until completed or cancelled
ADP-17 Active CO can disable; re-activation requires full new ceremony
ADP-20 Reconstructed secret hash-verified then zeroized — NEVER stored
ADP-25 Server generates random 256-bit ceremony secret internally

Share Lifecycle

# Decision
ADP-6 Shares tagged with domain_id, ownership distributed to custodians
ADP-24 Shares auto-destroyed on ceremony completion or cancellation
ADP-26 Ceremony initiation specifies custodian user IDs — atomic share creation
ADP-27 Progressive share submission — server collects until all N, then auto-activates
ADP-28 Partial shares stored encrypted in ceremony_submissions table
ADP-29 Duplicate submissions overwrite (allows custodian correction)

Config & Migration

# Decision
ADP-11 Per-domain ceremony key via KDF(KMS_CEREMONY_SECRET, domain_id)
ADP-16 Remove [roles] from TOML — only KMS_CEREMONY_SECRET env var remains
ADP-21 Additive migration (new tables + ALTER TABLE), keep old table for rollback
ADP-22 Manual CLI command to init default domain after upgrade
ADP-23 All backends (SQL + Redis-findex) support multi-domain via trait abstraction

REST API

# Decision
ADP-30 Domain-centric: /domains/{id}/ceremony/* and /domains/{id}/users/*
ADP-32 KMIP endpoint unchanged — domain_id in vendor attributes for Create
ADP-33 JSON for all domain endpoints (management API, not KMIP TTLV)
Full REST endpoint table
Method Path Description
POST /domains Create domain
GET /domains List domains
GET /domains/{id} Domain details + ceremony state
DELETE /domains/{id} Delete domain (only if Inactive)
POST /domains/{id}/users Add user to domain
DELETE /domains/{id}/users/{user} Remove user
POST /domains/{id}/ceremony/initiate Start ceremony
POST /domains/{id}/ceremony/submit-share Custodian submits share
GET /domains/{id}/ceremony/status Ceremony progress (X of N)
POST /domains/{id}/ceremony/cancel Cancel pending ceremony
POST /domains/{id}/ceremony/disable Deactivate completed ceremony
GET /domains/{id}/audit Ceremony audit trail

Error Handling / HA

# Decision
ADP-34 Fail-secure on DB unreachable — deny with 503
ADP-35 Reconstruction + activation atomic (single DB transaction)
ADP-36 409 Conflict for submissions in wrong ceremony state
ADP-37 Hash mismatch → reject, log security event, stay in SplitKeysIssued

Web UI

# Decision
ADP-10 Dedicated ceremony_audit table (append-only, per-domain)
ADP-38 Dedicated "Domains" nav section with list, detail, ceremony wizard
ADP-39 UI polls ceremony status every 5s
ADP-40 Context-aware UI — actions based on user role + ceremony state

Key New DB Tables

-- Domain partitions
CREATE TABLE domains (
    id          VARCHAR(128) PRIMARY KEY,
    name        VARCHAR(255) NOT NULL UNIQUE,
    total_parts INTEGER NOT NULL DEFAULT 2,
    state       VARCHAR(32) NOT NULL DEFAULT 'Inactive',
    version     INTEGER NOT NULL DEFAULT 0,
    secret_hash VARCHAR(64),     -- SHA-256 of ceremony secret
    created_by  VARCHAR(255),
    created_at  TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

-- Domain membership (CO candidates + operators)
CREATE TABLE domain_users (
    domain_id   VARCHAR(128) REFERENCES domains(id),
    user_id     VARCHAR(255),
    role        VARCHAR(32) NOT NULL, -- 'CryptoOfficer' or 'Operator'
    UNIQUE(domain_id, user_id)
);

-- Progressive share submissions (encrypted at rest)
CREATE TABLE ceremony_submissions (
    domain_id          VARCHAR(128) REFERENCES domains(id),
    share_index        INTEGER,
    encrypted_bytes    TEXT NOT NULL,
    submitted_by       VARCHAR(255),
    submitted_at       TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    UNIQUE(domain_id, submitted_by)
);

-- Append-only audit trail
CREATE TABLE ceremony_audit (
    id          INTEGER PRIMARY KEY AUTOINCREMENT,
    domain_id   VARCHAR(128) REFERENCES domains(id),
    event_type  VARCHAR(64) NOT NULL,
    actor       VARCHAR(255),
    timestamp   TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    details     TEXT -- JSON
);

-- Existing table modification
ALTER TABLE objects ADD COLUMN domain_id VARCHAR(128) REFERENCES domains(id);

@Manuthor
Manuthor force-pushed the feat/split_key branch 3 times, most recently from 1e1bb4b to f205799 Compare August 2, 2026 03:58
@Manuthor
Manuthor force-pushed the feat/split_key branch 2 times, most recently from d790761 to b0f0d07 Compare August 9, 2026 05:37
@Manuthor
Manuthor changed the base branch from develop to issue_983_user_id August 9, 2026 11:23
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants