Loading...
private.me Docs
Get Authorize
GOVERNANCE ACI

Authorize: K-of-N Threshold Authorization

Cryptographic multi-party authorization for enterprise governance. Critical operations require K approvals from N designated parties — no single approver can act independently.

XorIDA Threshold Sharing Information-Theoretic Security SOX / FINRA / GDPR Compliant
THE PROBLEM

Single-Approver Risk

Traditional authorization systems rely on procedural controls — approvals that exist in application logic but can be bypassed by privileged users, compromised accounts, or administrative overrides.

Insider Threats

A rogue administrator with database access can authorize high-value transactions by modifying approval records directly. Application-layer checks provide no defense when the attacker has system-level privileges.

Single Point of Failure

When a single approver has the authority to execute critical operations — production deployments, wire transfers, access grants — that individual becomes a single point of failure. Coercion, social engineering, or account compromise creates an unacceptable operational risk.

Compliance Gaps

Financial services regulations mandate dual control and separation of duties. SOX Section 404 requires segregation of authorization and execution. FINRA Rule 3110 demands supervisory review for high-risk transactions. GDPR Article 32 mandates technical measures to ensure security of processing.

Application-layer approval workflows satisfy the letter of these requirements but fail the spirit — a determined insider or sophisticated attacker can bypass procedural controls. Auditors increasingly demand cryptographic guarantees, not just access control lists.

REGULATORY PRESSURE
2026 SOX compliance trend: The era of treating Sarbanes-Oxley Section 404 as a tick-the-box annual exercise is over. Separation of duties is now subject to continuous monitoring and real-time validation. Organizations are adopting cryptographic enforcement mechanisms that scan millions of access combinations automatically.
THE SOLUTION

Cryptographic K-of-N Enforcement

Authorize transforms procedural authorization into cryptographic impossibility. An action payload is split into N shares via XorIDA threshold sharing. Any K shares can reconstruct the payload; K-1 or fewer reveal nothing.

Not Just Approval — Mathematical Guarantee

Traditional approval workflows track who said "yes" in a database. Authorize makes the action payload cryptographically impossible to execute without K physical approvals.

2-of-3
Default Threshold
<2ms
Split + HMAC
<1ms
Verify + Reconstruct
0
Plaintext Exposure

How It Works

1. CREATE AUTHORIZATION
import { createAuthorization } from '@private.me/authorize';

const config = {
  approvers: [
    { id: 'did:key:cto', name: 'CTO' },
    { id: 'did:key:ceo', name: 'CEO' },
    { id: 'did:key:ciso', name: 'CISO' },
  ],
  threshold: 2,  // 2-of-3 required
  action: 'deploy:production',
  expiresAt: Date.now() + 3600000  // 1 hour
};

const payload = new TextEncoder().encode('AUTHORIZED');
const result = await createAuthorization('deploy:production', payload, config);

// Distribute shares[0] to CTO, shares[1] to CEO, shares[2] to CISO
// Each share is individually HMAC-signed for integrity
2. COLLECT APPROVALS (ANY 2 OF 3)
const collected = [shares[0], shares[1]];  // CTO + CEO approve

const verified = await verifyAuthorization(collected, actionHash);
if (verified.ok) {
  const actionPayload = new TextDecoder().decode(verified.value);
  console.log('Action authorized:', actionPayload);  // "AUTHORIZED"
}
INFORMATION-THEORETIC SECURITY
XorIDA provides unconditional security: any K-1 or fewer shares reveal zero information about the payload. This is not computational hardness — it is mathematical impossibility. An attacker with infinite computational resources cannot reconstruct the payload from K-1 shares.
ARCHITECTURE

Authorization Lifecycle

1. Authorization Creation

An authorized requester (typically an operator or administrator) creates an authorization request for a specific action.

  1. Validate configuration: Ensure threshold ≥ 2, threshold ≤ N, and action string is non-empty.
  2. Pad payload: PKCS#7 padding to 16-byte boundary (prevents partial-block information leakage).
  3. Generate HMAC: HMAC-SHA256 on the padded payload for integrity verification.
  4. Split via XorIDA: Generate N shares via threshold secret sharing over GF(2).
  5. Hash action string: SHA-256 hash of the action string binds shares to this specific operation.
  6. Build share objects: Each share includes actionId, approverId, index, threshold, data, HMAC, originalSize.

2. Approval Flow

Shares are distributed to designated approvers via secure channels (email, secure messenger, in-person). Each approver receives exactly one share.

Out-of-band distribution: The authorization system does not transmit shares. The requester is responsible for secure delivery — this prevents the authorization service itself from becoming a single point of compromise.

Approval submission: Approvers submit their shares to the authorization server. The server stores encrypted shares (AES-256-GCM at rest) until the threshold is reached or the authorization expires.

3. Verification and Reconstruction

Once K shares are submitted, the authorization can be verified and the payload reconstructed.

  1. Validate share count: Ensure at least K shares are provided.
  2. Validate action binding: All shares must reference the same actionId.
  3. Reconstruct via XorIDA: Combine K shares to recover the padded payload.
  4. HMAC verification BEFORE use: Verify HMAC-SHA256 on reconstructed data. If integrity check fails, reject the authorization immediately — data may be tampered.
  5. Unpad payload: Remove PKCS#7 padding to recover the original action payload.
  6. Return to caller: The application receives the authorized payload and proceeds with the action.
HMAC-FIRST VERIFICATION
HMAC verification executes before the payload is returned to the caller. This is a strict security requirement: if integrity fails, the system rejects the authorization immediately. No "check the HMAC yourself" pattern — the library enforces it.

Audit Trail

Every authorization lifecycle event is logged to an append-only audit log (via @private.me/auditlog):

  • Authorization creation (timestamp, requester, action, threshold, approvers)
  • Share distribution (approverId, timestamp)
  • Share submission (approverId, timestamp)
  • Threshold reached (timestamp, K shares collected)
  • Verification success/failure (timestamp, HMAC result)
  • Authorization expiry or revocation

The audit log is HMAC-chained to prevent retroactive tampering. Each log entry references the HMAC of the previous entry, creating a tamper-evident chain.

USE CASES

Enterprise Governance Scenarios

💰
Financial Services
High-Value Wire Transfers

Dual control for wire transfers exceeding $100K. Treasury officer initiates, CFO + CEO approve. Cryptographic enforcement prevents rogue transfers.

SOX 404 • FINRA 3110
🚀
Engineering
Production Deployments

Code deployment requires 2-of-3 approvals from engineering leads. Prevents unauthorized production changes during incidents.

DevSecOps
🔐
Security
Cryptographic Key Rotation

Root certificate rotation requires CTO + CISO approval. Split custody prevents single-admin key compromise.

NIST SP 800-57
🏥
Healthcare
Sensitive Data Access

Access to patient records outside normal workflow requires dual approval from Privacy Officer + Department Head.

HIPAA § 164.308(a)(4)
🌐
Infrastructure
DNS Zone Modifications

Root zone changes require 3-of-5 approval from geographically distributed registrars. Prevents single-point DNS hijacking.

DNSSEC
🏛️
Government
Classified Data Release

Declassification requires approval from originating agency + reviewing authority. Threshold sharing enforces two-person integrity.

EO 13526
🔬
Pharmaceutical
Clinical Trial Unblinding

Emergency unblinding requires 2-of-3 approval from CRO + IRB + DSMB. Prevents premature trial compromise while preserving patient safety.

FDA 21 CFR Part 11
🏦
Banking
Customer PII Export

Bulk customer data export for regulatory inquiry requires Compliance Officer + Legal Counsel approval. Prevents unauthorized data exfiltration.

GLBA • GDPR Art. 32
THRESHOLD FLEXIBILITY
2-of-2: Maximum security, no fault tolerance. Both approvers required.
2-of-3: Default balanced mode. Any 2 of 3 approvers can authorize. Tolerates 1 unavailable approver.
3-of-5: High-value operations. Tolerates 2 unavailable approvers while requiring 3 independent approvals.
K-of-N: Custom thresholds for specific governance requirements.
PERFORMANCE

Benchmarks

Authorization overhead measured on Node.js 22.x, Intel Core i7-1185G7 @ 3.00GHz, single-threaded.

Operation Payload Size Latency Notes
Create (2-of-3) 256 bytes <2ms PKCS#7 pad + HMAC + XorIDA split
Create (2-of-3) 1 KB <3ms Typical JSON action payload
Create (3-of-5) 256 bytes <3ms More shares = slightly higher overhead
Verify + Reconstruct 256 bytes <1ms HMAC verify + XorIDA reconstruct + unpad
Verify + Reconstruct 1 KB <1.5ms Sub-millisecond for typical payloads
HMAC verification Any <0.3ms HMAC-SHA256 via Web Crypto API

Throughput

Authorization creation: ~500 authorizations/second (2-of-3, 256-byte payloads, single-threaded).

Verification: ~1000 verifications/second (reconstruction is faster than splitting).

Scalability

The authorize-cli enterprise server handles concurrent authorization workflows via in-memory state + JSONL persistence. No external database required. Horizontal scaling via multiple server instances with shared JSONL storage (NFS or object storage).

ZERO NETWORK CALLS
Authorization creation and verification are purely local operations. No API calls, no database queries during the cryptographic operations. Network latency appears only in share distribution (out-of-band) and share submission (REST API).
INTEGRATION

Enterprise CLI

The @private.me/authorize-cli package provides a production-ready HTTP server for managing authorization workflows.

Quick Start

1. INSTALL
pnpm add @private.me/authorize-cli
2. START SERVER
# Generate secrets
export AUTHORIZE_SHARE_ENCRYPTION_KEY=$(openssl rand -hex 32)
export AUTHORIZE_ADMIN_API_KEY=$(openssl rand -hex 32)

# Start server on port 4400
authorize-cli serve --port 4400 --data /var/lib/authorize
3. CREATE AUTHORIZATION
export AUTHORIZE_API_URL=http://localhost:4400
export AUTHORIZE_API_KEY=$AUTHORIZE_ADMIN_API_KEY

authorize-cli create \
  '{"operation":"transfer","amount":100000,"to":"alice@example.com"}' \
  did:key:approver1 \
  did:key:approver2 \
  did:key:approver3 \
  --threshold 2 \
  --expires 7200000
4. SUBMIT APPROVALS
authorize-cli submit <action-id> did:key:approver1 <share1-base64>
authorize-cli submit <action-id> did:key:approver2 <share2-base64>
5. VERIFY AUTHORIZATION
authorize-cli verify <action-id>
# Returns reconstructed payload if threshold reached and HMAC valid

REST API Endpoints

POST /authorizations

Create a new authorization. Requires admin or operator role. Returns actionId and shares.

POST /authorizations/:id/approvals

Submit an approval share. Requires operator role. Stores encrypted share until threshold reached.

GET /authorizations/:id

Retrieve authorization status. Returns submitted count, threshold, expiry, and status (pending/authorized/expired).

POST /authorizations/:id/verify

Verify and reconstruct authorization. Requires admin or operator role. Returns payload if threshold met and HMAC valid.

GET /audit-log

Retrieve audit trail. Requires auditor role. Returns HMAC-chained log entries.

RBAC (3 Roles)

Role Permissions Use Case
Admin Create authorizations, verify, read audit log, manage API keys System administrators
Operator Create authorizations, submit approvals, verify Application services, engineers
Auditor Read-only access to audit log Compliance officers, external auditors

Deployment

Docker: Official Docker image available. Mount data directory as volume for persistence.

Air-gapped: Zero external network dependencies. All state stored in local JSONL files.

High availability: Run multiple instances with shared JSONL storage (NFS, S3, or distributed filesystem).

Deployment

Production Deployment

Docker-ready. Air-gapped capable. Port 4400. 71 tests. Part of the Enterprise CLI Suite.

@private.me/authorize-cli provides a production-grade authorization server with full REST API, multi-party approval workflows, HMAC-chained audit logs, and cryptographic threshold enforcement. Integrates the complete @private.me/authorize package for enterprise governance deployments.

Docker Deployment

Docker Compose
# Pull and run the Authorize server
docker compose up -d authorize

# Verify health
curl http://localhost:4400/health
# {"status":"ok","version":"0.1.0","uptime":42}

# Air-gapped deployment
docker save private.me/authorize-cli > authorize-cli.tar
# Transfer to air-gapped environment
docker load < authorize-cli.tar
docker compose up -d

Environment Configuration

Required environment variables
# Generate secrets on first deployment
export AUTHORIZE_SHARE_ENCRYPTION_KEY=$(openssl rand -hex 32)
export AUTHORIZE_ADMIN_API_KEY=$(openssl rand -hex 32)

# Data directory for JSONL persistence
export AUTHORIZE_DATA_DIR=/var/lib/authorize

# Server configuration
export AUTHORIZE_PORT=4400
export AUTHORIZE_HOST=0.0.0.0

# Audit log configuration (optional)
export AUTHORIZE_AUDIT_RETENTION_DAYS=365
export AUTHORIZE_MAX_AUTHORIZATION_AGE_HOURS=72

Kubernetes Deployment

Kubernetes manifest
apiVersion: apps/v1
kind: Deployment
metadata:
  name: authorize-server
spec:
  replicas: 3
  selector:
    matchLabels:
      app: authorize
  template:
    metadata:
      labels:
        app: authorize
    spec:
      containers:
      - name: authorize
        image: private.me/authorize-cli:latest
        ports:
        - containerPort: 4400
        envFrom:
        - secretRef:
            name: authorize-secrets
        volumeMounts:
        - name: data
          mountPath: /var/lib/authorize
      volumes:
      - name: data
        persistentVolumeClaim:
          claimName: authorize-pvc

High Availability

Load-balanced deployment with shared storage
# Mount shared JSONL storage (NFS, EFS, or distributed filesystem)
docker run -d \
  --name authorize-1 \
  -p 4401:4400 \
  -v /mnt/shared/authorize:/var/lib/authorize \
  -e AUTHORIZE_SHARE_ENCRYPTION_KEY=$KEY \
  -e AUTHORIZE_ADMIN_API_KEY=$ADMIN_KEY \
  private.me/authorize-cli:latest

docker run -d \
  --name authorize-2 \
  -p 4402:4400 \
  -v /mnt/shared/authorize:/var/lib/authorize \
  -e AUTHORIZE_SHARE_ENCRYPTION_KEY=$KEY \
  -e AUTHORIZE_ADMIN_API_KEY=$ADMIN_KEY \
  private.me/authorize-cli:latest

# Load balancer routes to both instances
# Shared storage ensures consistent state
4400
Default port
~12
REST endpoints
71
Tests passing
0
External deps
Enterprise CLI Suite
Authorize CLI is part of the Enterprise CLI Suite — 21 self-hosted reference servers covering identity management, passwordless auth, secret sharing, verifiable computation, encrypted search, secure ingest, key transport, split storage, and more. All Docker-ready, air-gapped capable, with HMAC-chained audit logs and multi-role RBAC.
SECURITY

Security Guarantees

Information-Theoretic Security

XorIDA threshold sharing over GF(2) provides unconditional security: any K-1 or fewer shares reveal zero information about the payload. This is not computational hardness — it is mathematical impossibility. An attacker with infinite computational resources cannot reconstruct the payload from K-1 shares.

HMAC Before Reconstruction

HMAC-SHA256 verification executes on the reconstructed padded data before the payload is returned or trusted. If integrity fails, the authorization is rejected immediately. This prevents timing attacks and ensures data integrity.

Action Binding

Shares are bound to a specific action string via SHA-256 hash. Shares from one authorization cannot be used to authorize a different action. This prevents share replay across different operations.

Time-Limited Authorization

Optional expiresAt timestamp enables time-bounded authorization windows. Expired authorizations are automatically rejected during verification. This limits the window of opportunity for share collection and prevents stale authorizations.

Collusion Resistance

Any K-1 colluding approvers cannot reconstruct the payload. They must obtain the Kth share from a non-colluding party. This enforces true multi-party control.

No Math.random()

All randomness uses crypto.getRandomValues() via Web Crypto API. No weak PRNG, no predictable seeds.

PKCS#7 Padding

Block-aligned padding prevents partial-block information leakage. Padding is validated during unpad to detect tampering.

TRANSPORT SECURITY
Shares contain HMAC keys: The HMAC key is embedded in each share's hmac field. Transport-layer encryption (TLS) is mandatory for share distribution. Do not transmit shares over unencrypted channels.

Audit Trail Integrity

The audit log is HMAC-chained: each entry includes the HMAC of the previous entry. This creates a tamper-evident chain — modifying a historical entry breaks the chain and is immediately detectable.

COMPLIANCE

Regulatory Alignment

SOX Section 404 (Sarbanes-Oxley)

Requirement: Segregation of duties for financial reporting controls. The person who authorizes a transaction must not be the same person who records it.

How Authorize satisfies: Threshold authorization enforces cryptographic separation. A single approver cannot both initiate and authorize a high-value transaction. The K-of-N model ensures multiple independent parties must consent.

2026 trend: SOX auditors increasingly demand continuous monitoring and real-time validation of separation of duties. Authorize provides cryptographic enforcement that cannot be bypassed by privileged users.

FINRA Rule 3110 (Supervisory Procedures)

Requirement: Broker-dealers must establish supervisory procedures for high-risk transactions, including dual approval for large wire transfers.

How Authorize satisfies: Dual control is cryptographically enforced. A front-line officer can initiate a wire transfer, but a supervisor must provide a second approval share for the transaction to proceed.

GDPR Article 32 (Security of Processing)

Requirement: Implement appropriate technical measures to ensure a level of security appropriate to the risk, including measures to ensure ongoing confidentiality and integrity.

How Authorize satisfies: Threshold authorization is a technical measure (not procedural) that enforces multi-party control over sensitive data operations. The audit log provides tamper-evident evidence of all authorization decisions.

HIPAA § 164.308(a)(4) (Information Access Management)

Requirement: Implement policies and procedures for authorizing access to electronic protected health information (ePHI).

How Authorize satisfies: Access to patient records outside normal workflow can require dual approval (Privacy Officer + Department Head). The cryptographic threshold prevents single-admin access abuse.

NIST SP 800-57 (Key Management)

Recommendation: Cryptographic keys should be protected using split knowledge or dual control procedures.

How Authorize satisfies: Root certificate rotation and key generation ceremonies can require K-of-N approval from designated key custodians. This aligns with NIST recommendations for high-value cryptographic material.

GLBA (Gramm-Leach-Bliley Act)

Requirement: Financial institutions must implement administrative safeguards to protect customer information.

How Authorize satisfies: Bulk customer data exports for regulatory inquiries can require dual approval (Compliance Officer + Legal Counsel), preventing unauthorized data exfiltration.

CONTINUOUS COMPLIANCE
2026 regulatory landscape: Regulators are shifting from annual audits to continuous monitoring. Authorize's append-only audit log and cryptographic enforcement provide real-time evidence of compliance, not retroactive documentation.
LIMITATIONS

Known Limitations

No Per-Approver Digital Signatures (v0.1.0)

Shares are not individually authenticated with per-approver digital signatures. The publicKey field on Approver is reserved for a future version that will support Ed25519 signatures on submitted shares.

Current mitigation: Share submission requires authenticated API calls (Bearer token or DID-based auth in the enterprise CLI). The server logs which approver submitted each share.

HMAC Key Embedded in Shares

The HMAC key is included in each share's hmac field (format: key:signature). This is necessary for verification but means shares must be protected in transit.

Mitigation: Use TLS for all share transmission. Do not transmit shares over unencrypted channels. The enterprise CLI encrypts shares at rest with AES-256-GCM.

Advisory Expiry

The isExpired() function relies on Date.now() and is advisory only. The library checks expiry during verification, but enforcement depends on the caller not bypassing the check.

Mitigation: The enterprise CLI enforces expiry server-side and automatically cleans up expired authorizations.

No Revocation Propagation

If an approver's share is revoked, there is no automatic propagation mechanism to notify other approvers or the requester.

Mitigation: The enterprise CLI provides a revocation API that marks shares as invalid and emits audit log entries. Applications should poll for status changes.

Payload Size Practical Limit

While XorIDA can handle arbitrary payload sizes, very large payloads (>1MB) incur noticeable overhead. Authorization payloads should be action descriptors (JSON, typically <1KB), not bulk data.

Best practice: Authorize the action, not the data. For large data transfers, authorize a reference (hash, S3 key, database ID) and validate the reference before proceeding.

API REFERENCE

API Surface

Functions

createAuthorization(action, payload, config) → Result<AuthorizationResult, AuthorizeError>

Splits a payload into K-of-N shares via XorIDA. Pads with PKCS#7, generates HMAC, and binds shares to an action via SHA-256 hash. Returns actionId, shares, and actionHash.

verifyAuthorization(shares, actionHash) → Result<Uint8Array, AuthorizeError>

Reconstructs the payload from K shares. HMAC verification runs BEFORE the payload is returned. Returns the original payload bytes if successful.

verifyAuthorizationWithAction(shares, action) → Result<Uint8Array, AuthorizeError>

Same as verifyAuthorization but accepts the action string directly, computing the SHA-256 hash internally.

isExpired(config) → boolean

Returns true if the authorization has passed its expiresAt timestamp. Advisory only — enforcement is the caller's responsibility.

Types

Approver

Field Type Description
id string Unique identifier (DID or email)
name string Human-readable name
publicKey Uint8Array? Optional Ed25519 public key (future use)

AuthorizationConfig

Field Type Description
approvers Approver[] List of approvers (minimum 2)
threshold number K-of-N threshold (≥2, ≤N)
action string Action description (non-empty)
expiresAt number? Optional expiry (ms since epoch)

ApprovalShare

Field Type Description
actionId string UUID v4 action identifier
approverId string Approver ID this share is assigned to
index number Share index (0-based)
total number Total shares (N)
threshold number Required threshold (K)
data string Base64-encoded share data
hmac string Base64 HMAC (key:signature)
originalSize number Payload size before padding
ERROR HANDLING

Error Codes

Code Returned By Description
INVALID_CONFIG createAuthorization, verifyAuthorization Fewer than 2 approvers, threshold < 2 or > N, empty action, or mismatched action IDs across shares.
SPLIT_FAILED createAuthorization XorIDA split operation threw an exception internally.
HMAC_FAILED verifyAuthorization, verifyAuthorizationWithAction HMAC-SHA256 verification failed after reconstruction. Data integrity compromised — shares may be tampered.
RECONSTRUCT_FAILED verifyAuthorization, verifyAuthorizationWithAction XorIDA reconstruction failed or PKCS#7 unpadding produced invalid result.
INSUFFICIENT_APPROVALS verifyAuthorization, verifyAuthorizationWithAction Number of submitted shares is less than the required threshold.
ACTION_EXPIRED Application-level (via isExpired) Date.now() exceeds config.expiresAt.
APPROVAL_REVOKED Application-level An approval share has been marked as revoked (enterprise CLI only).

Error Details

All errors include a message field with a human-readable description. For INVALID_CONFIG, the message specifies which validation rule failed (e.g., "Threshold must be >= 2").

ACTIONABLE ERROR MESSAGES
Error messages are designed for developers, not end users. They include specific field names and validation hints. Applications should map error codes to user-friendly messages.
BUILDING BLOCKS

Dependencies

Package Relationship
@private.me/crypto Provides XorIDA split/reconstruct, HMAC-SHA256, PKCS#7 padding, base64 encoding, UUID generation.
@private.me/shared Provides Result<T, E> type and ok()/err() constructors for error handling.
@private.me/auditlog Optional integration for HMAC-chained audit trail of authorization events (used by authorize-cli).
@private.me/xid Optional integration for DID-based approver authentication (enterprise deployments).

Zero npm Dependencies

The @private.me/authorize library has zero npm dependencies beyond PRIVATE.ME platform packages. All cryptography uses Web Crypto API. No OpenSSL, no libsodium, no third-party crypto libraries.

SUPPLY CHAIN SECURITY
Minimal dependencies reduce supply chain attack surface. Every npm package in the dependency tree is a potential compromise vector. Authorize's zero-npm-deps design eliminates this risk.