| id | title | type | status | tags | ||||
|---|---|---|---|---|---|---|---|---|
DOC-SECURITY |
Security Model and Operational Guide |
specification |
approved |
|
This document provides comprehensive security information for developers and operators using wsc (WebAssembly Signature Component). It connects operational guidance to the underlying security analysis artifacts defined throughout the project's threat model, STPA analysis, and cybersecurity architecture.
- Overview
- Keyless Signing Security Model
- Certificate-Based Signing Security
- Security Guarantees
- Threat Model
- Operational Security
- Certificate Pinning
- Comparison with Other Systems
wsc provides two signing approaches, each with distinct security models:
- Keyless Signing - Ephemeral keys with OIDC identity and Rekor transparency log
- Certificate-Based Signing - Long-lived keys with X.509 PKI and hardware security
This document focuses primarily on keyless signing security (addressing Issues #4 and #2). The keyless signing module is modeled as [[CTRL-3]] in the STPA control structure; the data flows it participates in are [[DF-2]], [[DF-3]], [[DF-4]], and [[DF-7]], and the ephemeral key lifecycle is governed by [[CD-8]].
┌─────────────┐ ┌──────────────┐ ┌───────────┐
│ CI/CD │────▶│ OIDC Token │────▶│ Fulcio │
│ Environment │ │ (Identity) │ │ (Certs) │
└─────────────┘ └──────────────┘ └─────┬─────┘
│
┌──────────────────────────┘
│
▼
┌───────────────┐
│ Ephemeral │
│ ECDSA P-256 │◀───── Generated on-demand
│ Private Key │ Zeroized after use
└───────┬───────┘
│
│ Signs
▼
┌───────────────┐
│ WASM Module │
│ + Signature │
└───────┬───────┘
│
│ Upload
▼
┌───────────────┐
│ Rekor Log │◀───── Public transparency
│ (Timestamp + │ Inclusion proof
│ Proof) │ Checkpoint signature
└───────────────┘
The architecture maps to the following data flows: the OIDC token acquisition is [[DF-2]], certificate issuance from Fulcio is [[DF-3]], transparency log submission is [[DF-4]], and the ephemeral key material itself is [[DF-7]]. The signing module as a controller is [[CTRL-3]].
Keyless signing uses ephemeral ECDSA P-256 keys that exist only for the duration of a single signing operation. The full lifecycle is governed by [[CD-8]] (Ephemeral Key Lifecycle).
// Generated using cryptographically secure random number generator
let signing_key = SigningKey::<p256::NistP256>::random(&mut OsRng);Security Properties:
- Generated using OS-provided CSPRNG (
OsRng) - 256-bit key strength (128-bit security level)
- Never written to disk
- Never leaves process memory
The ephemeral private key is tracked as [[ASSET-009]] and the CSPRNG quality contributes to [[SP-3]].
let verifying_key = signing_key.verifying_key();
let public_key_bytes = verifying_key.to_encoded_point(false);Security Properties:
- Public key can be freely shared
- Used for Fulcio certificate request
- Encoded in uncompressed SEC1 format
let certificate = fulcio.get_certificate(&oidc_token, public_key, &proof)?;Process:
- Prove possession of private key (sign OIDC
subclaim) - Fulcio validates OIDC token
- Fulcio issues short-lived X.509 certificate (~10 minutes validity)
- Certificate binds public key to OIDC identity
This phase corresponds to data flow [[DF-3]] (Fulcio Cert). The Fulcio certificate is [[ASSET-011]], and the OIDC token consumed here is [[ASSET-010]].
Trust Assumptions:
- OIDC provider correctly authenticates user
- Fulcio CA is trusted and not compromised
- Network connection to Fulcio is secure (TLS)
let module_hash = Sha256::digest(&module_bytes);
let signature = signing_key.sign_digest(module_hash);Security Properties:
- Signs SHA-256 hash of WASM module
- Signature binds to exact module content
- Uses ECDSA with deterministic nonce (RFC 6979)
This step directly implements [[SP-1]] (Authenticity) and [[SP-2]] (Integrity).
let rekor_entry = rekor.upload_entry(&module_hash, &signature, &certificate)?;Process:
- Upload signature + certificate + hash to Rekor
- Rekor validates and timestamps the entry
- Returns signed entry timestamp (SET) and inclusion proof
- Provides public auditability
This phase corresponds to data flow [[DF-4]] (Rekor Submission). The Rekor log entry is [[ASSET-012]].
Security Properties:
- Immutable public log (append-only)
- Cryptographic proof of inclusion in log
- Timestamped by trusted timestamping authority
- Enables detection of misissuance or compromise
These properties implement [[SP-4]] (Freshness) and [[SP-5]] (Auditability).
// Automatic when signing_key goes out of scope
// SigningKey's internal SecretKey implements ZeroizeOnDropSecurity Properties:
- Private key bytes overwritten with zeros
- Happens even on panic/error (Rust Drop guarantee)
- Prevents key recovery from memory dumps
- Mitigates cold boot attacks
This phase is the terminal state of [[CD-8]] (Ephemeral Key Lifecycle). The zeroization control directly mitigates the attack scenarios modeled in [[AS-2]] (memory-based key extraction).
Implementation: See src/lib/src/signature/keyless/signer.rs:142-157
The trust model is structured around five threat agents ([[TA-1]] through [[TA-5]]) and the security properties ([[SP-1]] through [[SP-8]]) that must hold under their activity.
-
OIDC Provider (e.g., GitHub Actions)
- Correctly authenticates workflow identity
- Protects token issuance
- Provides authentic
subandissclaims - Compromise of this trust anchor is modeled by [[TA-1]]
-
Fulcio Certificate Authority
- Issues certificates only for valid OIDC tokens
- Properly validates proof of possession
- Certificate validity period is accurate (~10 min)
- Root CA private key is secure
- Compromise of this trust anchor is modeled by [[TA-2]]
-
Rekor Transparency Log
- Accepts and timestamps all entries honestly
- Provides correct inclusion proofs
- Signed tree heads (checkpoints) are authentic
- Log is append-only and immutable
- Compromise is modeled by [[TA-3]]
-
Cryptographic Primitives
- ECDSA P-256 is secure (no known practical attacks)
- SHA-256 is collision-resistant
- Random number generator is unpredictable
- Zeroize library correctly clears memory
- These underpin [[SP-1]] through [[SP-4]]
-
Rust Language & Libraries
- Memory safety prevents use-after-free, buffer overflows
- Type system prevents many logic errors
p256,ecdsa,webpkicrates are correctly implemented- Supply chain compromise of dependencies is modeled by [[TA-5]]
-
The Signer's Environment
- May be compromised or malicious
- Ephemeral key only exists during signing
- No long-lived secrets to steal
- Threat agent: [[TA-4]] (insider / compromised environment)
-
Network Infrastructure
- TLS protects in transit
- But assumes HTTPS is properly configured
- Certificate pinning provides defense-in-depth (see [[CR-7]], [[CD-4]], [[CV-6]])
-
Verification Environment
- Verifier must have correct Fulcio root CA
- Must check Rekor inclusion proof
- Must validate certificate at correct timestamp
Attack: Adversary steals OIDC token from environment variables. Modeled as [[TS-001]] and STPA attack scenario [[AS-1]].
Impact: Can request Fulcio certificate for stolen identity.
Mitigations:
- Tokens are single-use with short lifetime (~15 minutes)
- Token zeroized from memory after use (Issue #11)
- Rekor log provides audit trail of all signatures
- Token theft requires environment access (same as private key theft)
Residual Risk: LOW - Token lifetime limits exposure window. See [[RA-001]].
Attack: Memory dump or debugger extracts private key. Modeled as [[TS-002]] and STPA attack scenario [[AS-2]].
Impact: Can forge signatures for the duration of key's lifetime.
Mitigations:
- Key exists only during signing operation (<1 second)
- Zeroized immediately after use (Issue #14), governed by [[CD-8]]
- Requires attacker to time attack perfectly
- Signature is logged in Rekor (detectable)
Residual Risk: VERY LOW - Tiny attack window. See [[RA-002]].
Attack: Intercept communication with Fulcio/Rekor. Modeled as [[TS-003]] and STPA attack scenario [[AS-3]].
Impact: Could steal OIDC token, modify responses.
Mitigations:
- TLS encryption for all HTTPS requests
- Fulcio certificate chains to trusted root
- Rekor entries have signed timestamps
- Certificate pinning enforced (see [[CR-7]], [[CD-4]], [[CD-9]])
Residual Risk: LOW - Requires TLS compromise. See [[RA-003]].
Attack: Modify Rekor log after signature creation. Modeled as [[TS-004]] and STPA attack scenario [[AS-4]].
Impact: Could hide evidence of signature or forge timestamps.
Mitigations:
- Merkle tree inclusion proofs (Issue #15)
- Signed tree heads (checkpoints) from Rekor
- Gossip protocol for checkpoint consistency (Sigstore project)
- Multiple monitors can detect tampering
Residual Risk: LOW - Cryptographically protected. See [[RA-004]].
Threat: Fulcio or Rekor completely compromised.
Rationale: If core infrastructure is compromised, system security fails. This is a trust anchor. Mitigation requires infrastructure-level security (HSMs, monitoring, incident response) which is Sigstore's responsibility. Residual risk accepted as [[RR-1]].
Threat: Timing attacks, power analysis, electromagnetic emanation.
Rationale:
- p256 crate uses constant-time operations
- ECDSA nonce is deterministic (RFC 6979), eliminating nonce attacks
- Ephemeral keys reduce exposure window
- Production environments typically not vulnerable to physical side-channels
Residual risk accepted as [[RR-2]].
Threat: Shor's algorithm breaks ECDSA.
Rationale:
- Not currently practical
- Post-quantum migration is industry-wide effort
- Ephemeral keys limit retroactive compromise risk
- Will adopt post-quantum algorithms when standardized
Residual risk accepted as [[RR-3]].
These map directly to the cybersecurity goals [[CG-1]] through [[CG-8]]:
- Authenticity ([[CG-1]]) - Signature proves WASM module came from specific OIDC identity
- Integrity ([[CG-2]]) - Any modification to module invalidates signature
- Non-Repudiation ([[CG-3]]) - Public Rekor log prevents denial of signing
- Freshness ([[CG-4]]) - Rekor timestamp proves when signature was created
- Auditability ([[CG-5]]) - All signatures publicly logged and verifiable
- No Key Management ([[CG-6]]) - No long-lived private keys to protect
These limitations are captured as residual risks:
- Revocation ([[RR-4]]) - Cannot revoke a signature after creation (certificate expired anyway)
- Offline Verification ([[RR-5]]) - Requires Rekor access for inclusion proof
- Anonymity ([[RR-6]]) - OIDC identity is in certificate (intentional)
- Forward Secrecy - Compromise of Fulcio CA root invalidates all past signatures
| Property | Keyless | Certificate-Based |
|---|---|---|
| Offline verification | No (needs Rekor) | Yes |
| Key management | None | Complex |
| Transparency log | Yes (Rekor) | No |
| Hardware security | Optional | Yes (ATECC608) |
| Revocation | Expiry only | Expiry only |
| Internet required | Yes (signing) | No |
| Best for | CI/CD, cloud | IoT, embedded, air-gapped |
The operational guidance below connects to the cybersecurity requirements [[CR-1]] through [[CR-11]] and the verification procedures [[CV-1]] through [[CV-8]].
GitHub Actions Example:
permissions:
id-token: write # Required for OIDC token
steps:
- uses: actions/checkout@v4
- run: wasmsign2 sign --keyless -i module.wasm -o signed.wasmSecurity Checklist:
- Enable
id-token: writepermission - Verify workflow identity matches expectations
- Review Rekor log for unexpected signatures
- Use branch protection to control who can trigger workflows
These practices implement the operational controls described in [[CR-1]] and [[CR-2]].
Verification includes:
- Certificate chain validation (to Fulcio root CA) -- [[CV-1]]
- Certificate validity at Rekor timestamp -- [[CV-2]]
- Signature verification against module hash -- [[CV-3]]
- Rekor inclusion proof verification -- [[CV-4]]
- Optional: identity and issuer validation -- [[CV-5]]
Example:
KeylessVerifier::verify(
&module,
Some("https://github.com/owner/repo/.github/workflows/build.yml@refs/heads/main"),
Some("https://token.actions.githubusercontent.com")
)?;Monitoring supports [[CG-5]] (Auditability) and enables detection of scenarios described by [[TS-005]] through [[TS-008]].
Monitor Rekor for:
- Unexpected signatures from your identity
- Signatures outside normal build times
- Signatures for unknown modules
Tools:
- Rekor search API:
https://rekor.sigstore.dev/api/v1/log/entries/retrieve - Monitor by identity: Check for your OIDC subject claim
OIDC tokens are sensitive (see [[ASSET-010]]):
- Never log
ACTIONS_ID_TOKEN_REQUEST_TOKEN - Tokens are single-use but should be zeroized
- Use GitHub's OIDC provider security best practices
This guidance implements [[CR-3]] and helps prevent [[TS-001]] (OIDC Token Theft).
Outbound HTTPS Required:
https://fulcio.sigstore.dev- Certificate issuance ([[DF-3]])https://rekor.sigstore.dev- Transparency log ([[DF-4]])https://token.actions.githubusercontent.com- OIDC (GitHub) ([[DF-2]])
Firewall Rules:
- Allow outbound HTTPS (port 443)
- Certificate pinning enforced for defense-in-depth (see [[CR-7]])
These network controls implement [[CR-4]] and mitigate [[TS-003]] (MITM attacks).
Note: Currently no rate limiting (Issue #6)
- Fulcio/Rekor have their own rate limits
- Excessive signing may be throttled by Sigstore
Certificate pinning is a critical defense-in-depth control, modeled as cybersecurity requirement [[CR-7]], with design detail in [[CD-4]] and [[CD-9]], and verification in [[CV-6]]. The pinned certificates protect [[ASSET-010]] (OIDC Token) and [[ASSET-011]] (Fulcio Certificate) in transit.
Certificate pinning adds defense-in-depth protection for TLS connections to Sigstore endpoints (Fulcio and Rekor). Even if a trusted Certificate Authority is compromised, pinning prevents man-in-the-middle attacks by validating that server certificates match known fingerprints.
Threats Mitigated:
- CA compromise (rogue certificates from trusted CAs) -- [[TS-005]], [[AS-5]]
- DNS/BGP hijacking with valid certificates -- [[TS-006]], [[AS-6]]
- State-level adversaries with CA access -- [[TS-007]], [[AS-7]]
- Certificate mis-issuance attacks -- [[TS-008]], [[AS-8]]
Current State: Fully implemented and enforced
The wsc library includes complete certificate pinning with enforcement:
- SHA256 fingerprint validation for Fulcio and Rekor endpoints
- Custom
PinnedRustlsConnectorusing ureq'sConnectortrait - Custom
ServerCertVerifierimplementation using rustls - Support for multiple pinned certificates (rotation)
- Configurable pins via environment variables
Current Behavior:
- Certificate pinning is enforced for all Fulcio/Rekor connections
- Connections fail if certificates don't match expected pins
- Falls back to standard WebPKI validation only if pinning initialization fails
# Fulcio production endpoint
export WSC_FULCIO_PINS="sha256_fingerprint1,sha256_fingerprint2"
# Rekor production endpoint
export WSC_REKOR_PINS="sha256_fingerprint1,sha256_fingerprint2"
# Custom Sigstore instance
export WSC_FULCIO_PINS="custom_fingerprint"# Get current Fulcio certificate fingerprint
echo | openssl s_client -connect fulcio.sigstore.dev:443 -servername fulcio.sigstore.dev 2>/dev/null | \
openssl x509 -outform DER | sha256sum
# Get current Rekor certificate fingerprint
echo | openssl s_client -connect rekor.sigstore.dev:443 -servername rekor.sigstore.dev 2>/dev/null | \
openssl x509 -outform DER | sha256sumTo require that pinning be enforced (fail if cannot):
export WSC_REQUIRE_CERT_PINNING=1This will cause connection attempts to fail with an error if certificate pinning cannot be enforced due to HTTP client limitations. This implements the strict enforcement mode described in [[CD-9]].
Certificate pins should be rotated when Sigstore updates their TLS certificates:
- Pre-rotation: Add new certificate fingerprints alongside existing ones
- Grace period: Accept both old and new pins for 30-90 days
- Post-rotation: Remove deprecated pins after grace period
- Monitoring: Alert on pin mismatches to detect rotation events
When Enforced:
- Prevents MITM even with compromised CA
- Validates leaf certificate fingerprint
- Optionally validates intermediate certificates
- Combines with standard WebPKI validation (defense-in-depth)
These properties satisfy the verification criteria in [[CV-6]] and implement the cybersecurity design [[CD-4]].
src/lib/src/signature/keyless/cert_pinning.rs- Complete pinning implementationsrc/lib/src/signature/keyless/fulcio.rs- Fulcio client integrationsrc/lib/src/signature/keyless/rekor.rs- Rekor client integration
(See docs/security-analysis.md for comprehensive coverage)
Summary:
- Uses Ed25519 signatures with SHA-256
- Supports multi-signature workflows
- Hardware-backed keys (ATECC608)
- Offline verification capability
- Certificate expiry provides revocation
wsc's keyless signing is built on Sigstore infrastructure (Fulcio + Rekor) but targets WASM modules specifically.
| Feature | wsc | Cosign |
|---|---|---|
| WASM Support | Native | Via blob |
| Keyless | Yes | Yes |
| Fulcio | Yes | Yes |
| Rekor | Yes | Yes |
| Multi-signature | Composition | Attestations |
| Hardware keys | ATECC608 | Software only (keyless) |
| Offline | Cert mode | Key mode |
| Feature | wsc Keyless | Apple Code Sign | Windows Authenticode |
|---|---|---|---|
| Algorithm | ECDSA P-256 | RSA/ECDSA | RSA |
| Timestamp | Rekor | TSA | TSA |
| Hardware | Optional | Optional (T2) | Optional (HSM) |
| Transparency | Rekor | No | No |
| Revocation | Expiry | CRL/OCSP | CRL/OCSP |
| Key Mgmt | None | Complex | Complex |
| Cost | Free | $99+/year | $100+/year |
This section documents known security limitations that users should be aware of. Each limitation is tracked as a residual risk ([[RR-1]] through [[RR-6]]) and, where applicable, linked to a roadmap item ([[FEAT-1]] through [[FEAT-5]]).
Residual Risk: [[RR-4]] Roadmap: [[FEAT-1]]
Limitation: WSC does not implement OCSP (Online Certificate Status Protocol) or CRL (Certificate Revocation Lists) checking.
Impact: Cannot revoke a compromised signing certificate before its natural expiration.
Mitigation: Fulcio certificates have a 10-minute validity window, inherently limiting the exposure window. For long-lived certificates (non-Fulcio deployments), use short validity periods (1-7 days).
Roadmap: OCSP stapling planned for Q2 2026 for non-Fulcio deployments.
Residual Risk: [[RR-5]] Roadmap: [[FEAT-2]]
Limitation: Hardware Security Module support is scaffolded but not complete.
Impact: Cannot achieve Security Level 3+ under IEC 62443 without hardware-backed key storage.
Mitigation: Use file-based keys with strict permissions (0600), process isolation, and encrypted filesystems. The platform/ module provides the interface for future HSM integration.
Roadmap: HSM integration for ATECC608A, TPM 2.0, and NXP SE050 planned for Q2 2026.
Residual Risk: [[RR-2]] Roadmap: [[FEAT-3]]
Limitation: Key material in memory could be swapped to disk by the operating system.
Impact: Forensic recovery of key material from swap space theoretically possible.
Mitigation:
- Use
mlock()on production systems to prevent swapping - Use encrypted swap partitions
- Ephemeral keys reduce exposure (sub-second lifetime)
- Zeroization on drop minimizes window
Note: The zeroize crate ensures keys are cleared from memory, but cannot prevent OS-level swap writes before Drop is called.
Residual Risk: [[RR-5]] Roadmap: [[FEAT-4]]
Limitation: Keyless signature verification requires Rekor access for inclusion proof verification.
Impact: Air-gapped or offline environments cannot verify keyless signatures without pre-fetching Rekor entries.
Mitigation:
- Use certificate-based signing for offline environments
- Pre-fetch and distribute Rekor entries with modules
- The
--offlineflag supports verification with pre-distributed trust bundles
Residual Risk: [[RR-1]] Roadmap: [[FEAT-5]]
Limitation: OIDC tokens exist in memory for the duration of the signing operation.
Impact: Memory dump during signing could expose token (until expiration).
Mitigation:
- Tokens are zeroized immediately after use
- Token lifetime is typically <15 minutes
- GitHub Actions OIDC tokens are bound to specific workflow runs
For automotive (ISO/SAE 21434) and industrial IoT (IEC 62443) deployments, see:
- docs/THREAT_MODEL.md - STRIDE threat analysis (covers [[TS-001]] through [[TS-018]])
- docs/TARA_COMPLIANCE.md - Standards compliance mapping
- docs/KEY_LIFECYCLE.md - Key management procedures (covers [[CD-1]] through [[CD-9]])
- docs/INCIDENT_RESPONSE.md - Security incident runbook
Do not open public issues for security vulnerabilities.
Contact: [security contact from repository settings]
Include:
- Description of vulnerability
- Steps to reproduce
- Potential impact
- Suggested mitigation (if any)
- Fixed timing attack vulnerability - Replaced
==with constant-time comparison (ct_codecs::verify) for all cryptographic material comparisons insimple.rsandmulti.rs - Added intermediate buffer zeroization - Message buffers now wrapped with
Zeroizing<Vec<u8>>to prevent secret residue in memory - Release profile hardening - Added
overflow-checks = trueto detect integer overflow in release builds - Certificate pinning enforcement ([[CR-7]], [[CD-4]]) - Created custom
PinnedRustlsConnectorusing ureq'sConnectortrait to enforce certificate pinning for Fulcio and Rekor connections - TARA compliance documentation - Added comprehensive documentation for ISO/SAE 21434 and IEC 62443 compliance:
docs/THREAT_MODEL.md- STRIDE analysisdocs/TARA_COMPLIANCE.md- Standards mappingdocs/KEY_LIFECYCLE.md- Key management proceduresdocs/INCIDENT_RESPONSE.md- Security incident runbook
- Added ephemeral key zeroization (Issue #14) -- implements [[CD-8]]
- Added OIDC token zeroization (Issue #11) -- mitigates [[TS-001]]
- Implemented Rekor inclusion proof verification (Issue #15) -- implements [[CV-4]]
- Sanitized error messages for information disclosure (Issue #9) -- mitigates [[TS-009]]
- Added comprehensive zeroization tests (17 new tests)
- Implemented certificate pinning infrastructure (Issue #12) -- [[CR-7]]
- Complete SHA256 fingerprint validation
- Support for custom pins via environment variables
- Implemented Rekor checkpoint-based verification (Issue #1) -- [[CV-4]]
- Full certificate chain verification (Issue #16) -- [[CV-1]]
- Sigstore Documentation
- Fulcio CA
- Rekor Transparency Log
- ECDSA P-256
- RFC 6962: Certificate Transparency
- RFC 6979: Deterministic ECDSA
Last Updated: 2026-03-15 Addresses: Issues #2 (Security Model Documentation), #4 (Ephemeral Key Lifecycle), #12 (Certificate Pinning)