Skip to main content

Audit & evidence export

Every privileged action, approval, node report and certificate operation in Sectigo Edge is added to a hash-chained audit log. Each event commits to the one before it, so any deletion or edit breaks the chain. You can check that chain in three ways:

MethodWhat it provesWho uses it
Console integrity checkThe events loaded in your browser link correctly and end at the reported chain head.Operators, day to day
Portable proof exportOne issuance or revocation was approved by both trust domains, signed and anchored in a customer-witnessed checkpoint.Auditors, verifying offline
OTLP audit exportEach Mesh Node streams its own signed audit journal to your SIEM.Security operations

Check the audit chain in the console​

Audit evidence page with the tenant evidence chain banner, witness status, checkpoint details and a list of audit events
Audit evidence re-hashes the loaded events in your browser and shows the customer witness quorum.

ConsoleAudit evidence re-computes the hash of every loaded event in your browser and shows one of these labels:

LabelMeaningAction
Verifying audit chain…The check is still running.Wait.
No audit events yetThe chain starts with the first recorded action.None.
Chain verified from genesisEvery event from the first one has been re-hashed and links correctly.None.
Recent events verifiedThe loaded window (events #from–#to) is verified. Older events are covered by exported proofs.None.
Audit chain could not be verifiedAn event does not match its recorded hash or predecessor link, or the window does not end at the reported head.Refresh. If the label persists, export a proof and investigate. Treat this as a potential incident.

The banner also shows the customer witness quorum: how many of your Mesh Nodes have independently checked and signed the latest checkpoint, for example 2/2 witnessed. Because the witnesses are your own nodes, a cloud-side fork of the log can be detected.

FieldMeaning
CheckpointThe sequence number of the latest signed checkpoint, or Not anchored
Distinct signaturesWitness signatures received, out of the number required
Customer nodesThe nodes that witnessed it, or Waiting for an eligible Mesh Node

Export a portable proof​

A portable proof is a single JSON bundle for one transaction (an issuance, plus its revocation if there is one). It can be verified without access to Sectigo, Cloudflare or your Mesh Nodes.

  1. Open ConsoleAudit evidence.
  2. Select Export portable proof. The console exports the most recent transaction in the loaded events and downloads sharppki-evidence-<transaction-id>.json.
  3. To export a specific transaction, call the API directly: POST /api/v1/transactions/<transaction-id>/evidence.

Export creates a fresh checkpoint and waits until enough of your Mesh Nodes have witnessed it. If not enough have, export fails with:

audit_customer_witness_pending: Customer audit witness quorum is pending (1/2); keep eligible Mesh Nodes connected and retry

Keep the eligible nodes online and retry. Witnessing happens over the nodes' normal outbound connection.

What the bundle proves​

  • The manifest has not changed since export.
  • Every customer approval signed the identical transaction. The quorum consists of distinct, independently pinned Mesh Node keys.
  • Your decision and Sectigo's decision allowed the same policy version, policy content, workload profile, algorithm and lifetime.
  • Any capability evidence used was fresh at the time of the transaction.
  • The protected signer's receipt binds the evidence, CA provider, key reference, certificate serial, validity and the signer registry generation.
  • An unbroken hash-chain path leads to a signed audit checkpoint that a quorum of your nodes witnessed.
  • If the certificate was revoked, the revocation has its own signer receipt and audit commitment.

Verify a proof offline​

The verifier is the sharppki-verify command from the Sectigo Edge workspace's evidence-verifier package. It is not published to a public registry. Build the workspace once with npm run build, then run the command with npx from inside the workspace. Never trust the public keys that come inside a bundle. The verifier uses only the keys in a trust file that you build from your own independent records.

  1. Build a trust file, pinned-trust.json, from keys you collected independently:

    {
    "audit_keys": { "audit-production-2026-01": "<base64url Ed25519 public key>" },
    "protected_signer_keys": { "receipt-production-1": "<base64url Ed25519 public key>" },
    "registries": { "42": "<base64url canonical registry SHA-256>" },
    "nodes": {
    "node-production-a": "<base64url Ed25519 public key>",
    "node-production-b": "<base64url Ed25519 public key>"
    },
    "minimum_audit_witnesses": 2
    }
  2. Set minimum_audit_witnesses to your approved customer witness policy. It defaults to 1. Use 0 only for legacy evidence created before customer witnessing existed.

  3. Run the verifier.

auditor-laptop (bash)
npx sharppki-verify --evidence sharppki-evidence-tx_7d41c2.json --trust pinned-trust.json
{
"verified": true,
"tenant_id": "acme-corp",
"transaction_id": "tx_7d41c2",
"manifest_sha256": "x3k9Qw...",
"checkpoint_sequence": 18342,
"audit_witness_node_ids": ["node-production-a", "node-production-b"],
"signer_registry_version": 42,
"approver_node_ids": ["node-production-a"],
"certificate_serial": "4f1a9c0e7b22d3",
"status": "issued"
}

A failed verification prints the reason and exits with a non-zero status. The verifier rejects missing, duplicate, untrusted, rebound or under-quorum witness receipts. It checks capability freshness against the time of the transaction, so archived proofs remain valid after the evidence itself has expired.

Keep old verification keys

Keep every audit, signer, registry and node key generation for at least the full retention period of your certificates, revocations and evidence. Removing an old key does not revoke old evidence, but it makes that evidence impossible to verify.

Export node audit logs to your SIEM (OTLP)​

Each Mesh Node can stream its complete signed audit journal to an OpenTelemetry Collector over OTLP/HTTP. The collector address, trust roots and client credential stay in your environment. They are never sent to the cloud.

Add these settings to the node's config.json:

{
"otlp_audit_enabled": true,
"otlp_audit_exporter_id": "primary-siem",
"otlp_audit_endpoint": "https://otel-collector.example.com:4318/v1/logs",
"otlp_audit_trust_bundle_file": "/etc/edgepki/otel/ca.pem",
"otlp_audit_client_certificate_file": "/etc/edgepki/otel/client.pem",
"otlp_audit_client_private_key_file": "/etc/edgepki/otel/client-key.pem",
"otlp_audit_batch_size": 32,
"otlp_audit_request_timeout_seconds": 10,
"otlp_audit_poll_interval_seconds": 5
}
SettingRule
otlp_audit_endpointMust be exactly https://host[:port]/v1/logs. No user info, query string, fragment, plain HTTP or redirects. Proxy environment variables are ignored.
TransportTLS 1.3, with a separately pinned collector CA bundle and a valid client certificate (client-auth EKU).
Client key fileA regular file, not a symlink, readable only by the node service. On Windows, an inheritance-protected DACL limited to the service identity, SYSTEM and Administrators.
otlp_audit_batch_size1–64
otlp_audit_request_timeout_seconds2–60
otlp_audit_poll_interval_seconds1–300
Disabled exporterLeave out every other otlp_audit_* field. Leftover settings are rejected, not ignored.

Delivery is at least once. The node advances its signed cursor only after the collector accepts the whole batch. Use the x-sectigo-edge-audit-batch header as your deduplication key. Each log body is the complete node-signed event. Keep it unchanged so it can be verified later.

If the collector is unreachable, a backlog builds up but nothing is lost. The node reports degraded and keeps working as a trust participant. For Helm, use otlpAudit.enabled, otlpAudit.exporterId, otlpAudit.endpoint and otlpAudit.existingSecret. See Kubernetes (Helm).

Monitoring for the exporter is covered in Monitoring & alerts.