Skip to content

Latest commit

 

History

History
357 lines (280 loc) · 11.8 KB

File metadata and controls

357 lines (280 loc) · 11.8 KB

Sovereign Node Key — Production Authorization & Integrity

This document explains what the Sovereign Node Key system is, what it proves, and how to use it safely.

Overview

A Sovereign Node Key is a production authorization credential consisting of:

  1. Node identity — Ed25519 keypair uniquely identifying a provisioned node
  2. Authorization record — Operator-signed proof that this node is authorized for protected operations
  3. Repository commitment — SHA-256 hash of repository state at key generation time
  4. Prior-art timestamp — Tamper-evident record of when this work existed
  5. Signer identity — Public key for signature verification

What It Proves

Node Authorization (NEW)

✓ The PAX-Coder authority has provisioned and authorized this node
✓ The authorization is cryptographically bound to this node's public key
✓ The authorization is operator-signed and cannot be self-created
✓ Protected operations require a valid authorization record
✓ Unauthorized, revoked, or expired nodes are denied

Integrity

✓ The repository has not been tampered with since the key was generated
✓ Every file's hash is recorded in manifest.json
✓ The manifest itself is committed in prior_art.json

Timestamp

✓ This code existed at a specific UTC time
✓ The git commit hash is cryptographically tied to that moment
✓ The prior-art timestamp is tamper-evident (local or Bitcoin-anchored)

Authenticity

✓ Outputs signed with this key were produced by the holder of .node_sk
✓ The public key (node_pk.pem) can verify any signature
✓ No one else can sign with this key (assuming the private key remains private)

Non-Repudiation

✓ The signer cannot later deny having created the signature
✓ The signature proves possession of the private key at the time of signing

What It Does NOT Prove (Alone)

Node Authorization (Without Authorization Record)

✗ Node identity alone does not grant authorization
✗ A valid signature does not grant authorization
✗ Possession of a node key does not grant authorization

Authorization requires: valid operator-signed authorization record + ACTIVE status + valid lifetime + non-revoked status

Legal Ownership

✗ Does the signer own the work?
✗ Can the signer license it?
✗ Are there copyright claims?

Not embedded in the crypto. Use separate legal instruments (licenses, trust deeds, copyright notices).

Work Quality

✗ Is the code correct?
✗ Does it do what it claims?
✗ Is it actually proven?

Not proven by this system. Use formal verification, testing, and code review.

Blockchain Confirmation

✗ Is this anchored to Bitcoin?
✗ Is the timestamp immutable?
✗ Can this be reversed?

Not unless explicitly anchored. The timestamp is local; see prior_art.json status for Bitcoin confirmation status.

Security Properties

Confidentiality

  • The private key MUST remain private
  • If compromised, all signatures are worthless
  • Rotate the key immediately if compromise is suspected

Integrity

  • The public key is safe to share
  • The manifest and prior-art record must not be modified after commitment
  • Verification scripts detect tampering

Authenticity

  • Only the private-key holder can create valid signatures
  • The public key proves who signed

Accountability

  • The public key is permanently associated with all outputs
  • There is no anonymous signing

Private Key Management

Never Do This

✗ Commit .node_sk to git
✗ Upload .node_sk to GitHub
✗ Email or message the private key
✗ Store in plaintext in cloud storage
✗ Share the private key with anyone
✗ Use weak file permissions (must be 400)
✗ Keep the private key in a public directory

Do This Instead

✓ Generate the key with ./generate_node_key.sh
✓ File permissions are set to 400 automatically
✓ Keep in a secure local directory (e.g., ~/.pax-node-keys/)
✓ Backup encrypted (e.g., to a YubiKey, hardware wallet, or encrypted USB)
✓ Rotate periodically (e.g., annually)
✓ Use environment variables when signing (never hardcode the key)

Example secure usage:

export PAX_NODE_KEY=$(cat ~/.pax-node-keys/node_sk | xxd -p | tr -d '\n')
openssl dgst -sha256 -sign ~/.pax-node-keys/node_sk output.ptx
unset PAX_NODE_KEY  # Clear from environment after use

Verification Procedure

For Your Own Outputs

Verify that all cryptographic artifacts are consistent:

cd sovereign
./verify_node_key.sh

Checks:

  • Public files exist and are valid JSON
  • Private key has correct permissions (400)
  • Git commit is in repository history
  • Repository commitment hash is correct
  • No private key material leaked to git

For Someone Else's Outputs

  1. Get the public key
    From their node.json:

    "public_key_hex": "..." 
  2. Get the prior-art record
    From their prior_art.json:

    {
      "git_commit": "...",
      "repository_sha256": "...",
      "created_at_utc": "..."
    }
  3. Verify the signature

    openssl dgst -sha256 -verify <(echo "PUBLIC_KEY_HEX" | xxd -r -p) \
      -signature output.sig output.ptx
  4. Check the timestamp
    The created_at_utc field is when they claimed the key was generated
    The git_commit is the repository state at that time
    Compare both to independent sources

  5. Spot-check the manifest
    Pick a few files from manifest.json and verify:

    sha256sum file1 file2 file3  # Should match values in manifest

Trust Boundaries

Trust Assumption: Private Key is Private

If the private key is compromised, all signatures are worthless. The security model collapses.

Trust Assumption: Public Key is Authentic

If you receive the public key through an insecure channel, you cannot trust the signatures. Use a secure channel (e.g., GitHub, verified fingerprints, institutional databases).

Trust Assumption: Git History is Honest

The system assumes git commits are immutable. If the repository is force-pushed or the git history is rewritten, the timestamps are no longer reliable.

Weaker Assumption: Clocks are Roughly Synchronized

Timestamps are local UTC. No assumption is made about perfect clock accuracy; only that times are roughly correct.

Attack Scenarios

Scenario 1: Private Key Compromise

If someone steals the private key:

  • They can sign fake outputs
  • All signatures become untrustworthy
  • Immediate rotation is required

Mitigation:

  • Keep private key offline when not in use
  • Use hardware security modules (YubiKey, etc.)
  • Monitor signature usage for anomalies
  • Rotate the key if compromise is suspected

Scenario 2: Repository Tampering

If git history is rewritten:

  • Repository commitment hash no longer matches
  • verify_node_key.sh will detect the mismatch
  • The prior-art record is still valid (git commit hash is immutable once broadcast)

Mitigation:

  • Repository should use branch protection and signing requirements
  • Keep clones as offline backups
  • Publish git commits to multiple sources (GitHub, git server, etc.)

Scenario 3: Timestamp Forgery

If someone falsifies the timestamp:

  • The created_at_utc field in node.json is under their control
  • Only verifiable via external sources (blockchain, timestamping service)
  • The git commit hash is the real proof (git commits are immutable once broadcast)

Mitigation:

  • Anchor the prior-art record to Bitcoin or a timestamping service (see OpenTimestamps)
  • The unanchored timestamp is only as trustworthy as the git history
  • status field in prior_art.json indicates confirmation level

Scenario 4: Man-in-the-Middle Attack

If someone intercepts the public key:

  • You cannot trust signatures verified with the intercepted key
  • You may be verifying signatures from an attacker, not the real signer

Mitigation:

  • Retrieve the public key from an authenticated source (GitHub, institutional database)
  • Verify fingerprints over multiple channels
  • Use HTTPS with certificate pinning
  • Compare public key fingerprints across independent sources

Rotation

When to Rotate

  • Annually (as part of security hygiene)
  • Immediately if compromise is suspected
  • When the key holder leaves the organization
  • After a security audit recommends rotation

How to Rotate

  1. Generate a new key: ./sovereign/generate_node_key_v2.sh
  2. Create a rotation record that includes:
    • Old node ID
    • New node ID
    • Reason for rotation
    • Timestamp
    • Signature by the old key (proving continuity)
  3. Commit new key files + rotation record
  4. Keep old private key in secure archive (do not delete)
  5. Announce the rotation (e.g., update documentation)

Rotation Record Example

{
  "old_node_id": "pax-coder-1234567890",
  "new_node_id": "pax-coder-1234567999",
  "old_public_key": "...",
  "new_public_key": "...",
  "rotation_timestamp": "2026-08-18T00:00:00Z",
  "reason": "scheduled annual rotation",
  "signed_by_old_key": "..."
}

Disaster Recovery

If Private Key is Lost

  1. Create a key-loss record (signed by the new key)
  2. Rotate to a new key
  3. Document the loss (for audit trail)
  4. Disable the old key if possible

If Private Key is Stolen

  1. Assume all signatures are compromised
  2. Rotate immediately to a new key
  3. Verify no unauthorized signatures exist
  4. Publish a security notice
  5. Update all dependent systems

If Repository is Corrupted

  1. Verify against a known-good clone
  2. Check the git commit hash in prior-art records
  3. If mismatch, investigate the corruption
  4. Restore from backup if necessary

CI/CD Integration

Add these checks to your CI/CD pipeline:

Secret Scanning

- name: Scan for private key material
  run: |
    if git grep -l "PRIVATE\|BEGIN.*KEY\|-----END" -- sovereign/ \
       | grep -v "\.md\|\.txt"; then
      echo "ERROR: Private key material detected in tracked files"
      exit 1
    fi

Integrity Verification

- name: Verify node key integrity
  run: |
    cd sovereign
    bash verify_node_key.sh

Manifest Validation

- name: Validate manifest JSON
  run: |
    jq . sovereign/manifest.json sovereign/node.json sovereign/verification.json

Permissions Check

- name: Ensure .node_sk is not tracked
  run: |
    if git ls-files | grep "\.node_sk"; then
      echo "ERROR: .node_sk should not be tracked by git"
      exit 1
    fi

Questions & Answers

Q: Is this blockchain-based?
A: No. The timestamps are local. Optional: anchor to Bitcoin via OpenTimestamps for immutability.

Q: Can I use RSA instead of Ed25519?
A: Yes, but Ed25519 is smaller, faster, and more secure. RSA requires larger keys.

Q: What if multiple people have the same private key?
A: Don't share the private key. Generate separate keys for each person; they'll have different node IDs.

Q: Can I sign outputs retroactively?
A: Yes, but the signature will reflect the current date, not the date the code was written.

Q: What about privacy?
A: The node ID and public key are publicly visible. If you want to hide your identity, use a different node identity for different projects.

Q: Can I revoke a key?
A: Yes, through key rotation. Mark the old key as revoked in the rotation record. The old signatures remain valid (you can't revoke history).

References


Last updated: 2026-08-18
System version: 1.0.0
License: BSL-1.1 / AGPL-3.0 / MPL-2.0