Attestor External Transparency Mirror Exchange

Audience: Attestor / Platform operators who must publish local transparency evidence to an external log for audit or cross-site reconciliation, including in sealed and air-gapped sites.

Purpose

This runbook describes how operators mirror Stella Ops local transparency entries to an approved external Rekor-compatible log without making that log a runtime dependency.

Local transparency remains authoritative. External mirror receipts are additive evidence for third-party audit, publication, or cross-site reconciliation.

Choose The Mode

ModeUse whenDo not use when
Sealed local-onlyThe installation must remain fully disconnected.External publication is contractually required.
Connected-window syncA temporary, approved egress path can be opened from Attestor to the external target.Policy forbids direct egress from the sealed site.
Manual schedule/import exchangeThe sealed site can move files through controlled media or a transfer station.The connected relay cannot be trusted to validate and sign return files.

Required Trust Inputs

Never place private keys, bearer tokens, client secrets, registry credentials, or external-log credentials in schedule or import files.

Required Scopes

Every transparency exchange endpoint is gated by an Attestor authorization policy. The policy names are colon-form, but the underlying token scope claim values are dot-form:

Policy (endpoint requirement)Accepted scope claim values
attestor:read (all GET targets/reports/batches)attestor.read, attestor.verify, or attestor.write
attestor:write (target upsert/enable/disable, external-sync:run, schedule/relay-import/import endpoints)attestor.write
attestor:verify (attestation verify)attestor.verify or attestor.write

All write endpoints in this runbook require attestor.write; the read-back endpoints accept attestor.read (or any higher scope). A configured Attestor service-to-service bypass also satisfies these policies. Note: these dot-form attestor.* scopes are Attestor-local (registered as authorization policies in AttestorWebServiceComposition) and are not present in the central StellaOpsScopes catalog, which instead exposes attest:read, attest:create, attest:admin, and sbom:attest.

Configure External Targets

Use Attestor APIs, CLI, or UI controls backed by these APIs; do not edit attestor.external_transparency_targets manually except during break-glass database recovery.

  1. Create or update the target:

    POST /api/v1/transparency/targets
    Content-Type: application/json
    
    {
      "name": "relay-eu",
      "kind": "rekor-compatible",
      "endpointUrl": "https://rekor-relay.example.test",
      "trustRootRef": "trust-roots/transparency/relay-eu.pem",
      "authRef": "secret:attestor/relay-eu/token",
      "enabled": false,
      "requiredCryptoProfileId": "fips",
      "operatorLabel": "maintenance-window-2026-05-24",
      "metadataJson": "{\"region\":\"eu\"}"
    }
    

    authRef must be a secret reference (secret:..., vault:..., or authref:...); raw bearer tokens and private material are rejected. requiredCryptoProfileId records the regional crypto expectation used by schedules/imports and audit reports. The certificate and private key still come from Authority/Platform trust administration and the crypto-provider registry.

  2. Read target status before opening a window:

    GET /api/v1/transparency/targets
    GET /api/v1/transparency/targets/{targetId}
    

    Check unconfigured, enabled, authRefConfigured, requiredCryptoProfileId, status.pendingCount, status.failedCount, status.mirroredCount, status.lastMirroredLocalIndex, and status.lastError.

  3. Enable the target only for an approved connected window:

    POST /api/v1/transparency/targets/{targetId}:enable
    POST /api/v1/transparency/targets/{targetId}:disable
    

    Leave targets disabled outside approved windows unless local policy allows a scheduled worker.

Connected-Window Sync

Use this flow when the sealed site is allowed to open a bounded network path.

  1. Confirm the target is configured and disabled-by-default external sync has been explicitly enabled for the maintenance window.

  2. Run a dry-run over the intended target selection:

    POST /api/v1/transparency/external-sync:run
    Content-Type: application/json
    
    {
      "targetNames": ["relay-eu"],
      "maxEntries": 100,
      "maxRuntimeSeconds": 300,
      "dryRun": true,
      "stopOnFirstHardError": true,
      "operatorLabel": "maintenance-window-2026-05-24"
    }
    
  3. Open the approved egress path.

  4. Run the bounded sync with target allow-list, maximum entries, maximum runtime, and stop-on-hard-error settings:

    POST /api/v1/transparency/external-sync:run
    Content-Type: application/json
    
    {
      "targetNames": ["relay-eu"],
      "maxEntries": 100,
      "maxRuntimeSeconds": 300,
      "dryRun": false,
      "stopOnFirstHardError": true,
      "operatorLabel": "maintenance-window-2026-05-24"
    }
    
  5. Read the durable sync report:

    GET /api/v1/transparency/external-sync/reports?targetName=relay-eu&operatorLabel=maintenance-window-2026-05-24
    GET /api/v1/transparency/external-sync/reports/{batchId}
    
  6. Close the egress path.

  7. Verify:

    • entries mirrored count;
    • skipped duplicates count;
    • failed entries and retryability;
    • last mirrored local index per target;
    • external receipt digest for each mirrored entry.

Failure rule: failed external sync does not invalidate local receipts. It leaves per-target mirror state as mirror_failed or mirror_pending.

Compose keeps this flow disabled unless the operator sets:

ATTESTOR_EXTERNAL_TRANSPARENCY_SYNC_ENABLED=true
ATTESTOR_EXTERNAL_TRANSPARENCY_WORKER_ENABLED=false

Set ATTESTOR_EXTERNAL_TRANSPARENCY_WORKER_ENABLED=true only for scheduled sync windows. Manual API triggers work with the worker disabled.

If external-sync:run is called while external sync is disabled, the endpoint returns 409 Conflict with code external_transparency_sync_disabled. Enable sync (ATTESTOR_EXTERNAL_TRANSPARENCY_SYNC_ENABLED=true, which sets attestor:transparency:externalSync:enabled=true) and configure at least one enabled target before retrying.

Manual Schedule/Import Exchange

Use this flow when the sealed site cannot open any direct network path.

Sealed Site: Create Schedule File

  1. Select local transparency entries by index range, timestamp range, artifact kind, or explicit UUID list.

  2. Generate a schedule file with:

    • manifest.json;
    • entries/*.json;
    • certificate.json;
    • manifest.sig;
    • checksums.txt. The service API is: POST /api/v1/transparency/exchange/schedules.

    Request fields:

    • targetIds or targetNames;
    • uuids, localIndexStart, localIndexEnd, createdAfter, createdBefore, and/or artifactKind;
    • limit;
    • siteId, attestorInstanceId, mediaId, and operatorLabel;
    • requiredCryptoProfileId.

    The response is a TransparencyExchangeFilePackage with base64-encoded file contents. Operators may write those files to the removable-media directory without changing their bytes.

  3. Verify the schedule file locally before transfer:

    • checksums match;
    • manifest signature verifies;
    • certificate is trusted, active, and valid for the regional crypto profile;
    • all entry descriptors match local transparency rows.
  4. Record the schedule id, manifest digest, media id, operator, and transfer ticket in the audit trail.

  5. Transfer the file through approved removable media or transfer station.

  6. Confirm schedule status without reading package bytes:

    GET /api/v1/transparency/exchange/batches?direction=schedule&operatorLabel=<operator-label>
    GET /api/v1/transparency/exchange/batches/{batchId}
    

Connected Relay: Produce Import File

  1. Validate the schedule file before any external submission.

  2. Submit the selected local entries to the approved external target.

  3. Verify each returned external receipt against the local entry digest from the schedule file.

  4. Generate an import file with:

    • import-manifest.json;
    • receipts/*.json;
    • certificate.json;
    • import-manifest.sig;
    • checksums.txt. The service API is: POST /api/v1/transparency/exchange/relay-imports.

    Request fields:

    • schedulePackage;
    • optional targetIds or targetNames to further narrow the schedule targets;
    • relayId, operatorLabel, and requiredCryptoProfileId.
  5. Record target id, target log URL, external UUID/index range, receipt digests, relay id, operator, and transfer ticket.

  6. Transfer the import file back to the sealed site.

Sealed Site: Validate And Import

  1. Validate checksums and import-manifest signature.
  2. Validate the signing certificate:
    • trusted by Authority/Platform trust state;
    • not expired;
    • not revoked;
    • allowed for transparency exchange;
    • algorithm matches the active regional crypto profile.
  3. Validate every receipt:
    • source schedule id matches;
    • local UUID/index exists;
    • local bundle digest matches;
    • external proof/checkpoint verifies for the returned receipt;
    • duplicate receipts are idempotent.
  4. Validate the returned file with POST /api/v1/transparency/exchange/imports:validate. The request body carries the returned TransparencyExchangeFilePackage as importPackage, plus an optional requiredCryptoProfileId.
  5. Apply the import file with POST /api/v1/transparency/exchange/imports:apply. The request body carries the same importPackage plus optional operatorLabel and requiredCryptoProfileId.
  6. Read the import status through GET /api/v1/transparency/exchange/batches?direction=sealed_import&operatorLabel=<operator-label>.
  7. Store the schedule/import file hashes with the exchange-batch metadata.

Failure rule: if validation fails, do not partially import the file unless the implementation explicitly reports an idempotent per-receipt apply result. Keep the local receipt state authoritative and record the failed import reason.

Implementation note: Attestor owns the package validation and receipt import workflow, but the signing certificate identity is resolved through Authority/Platform trust administration. Default Attestor dependency injection registers fail-closed placeholders for IInstallationCertificateResolver and ITransparencyExchangeSigner; a deployment must override them with the Authority/Platform-backed resolver and regional crypto signer before manual exchange packages can be minted or accepted.

Rollback And Retry

Local signing, local anchoring, verification replay, and release decisions that only require the Stella local transparency receipt continue to work when an external mirror is unavailable. External mirror outages leave affected entries in mirror_pending or mirror_failed; they do not invalidate attestor.local_transparency_entries and must not block sealed-site operation.

Connected-window retry:

  1. Leave the target enabled only for the approved window.
  2. Re-run POST /api/v1/transparency/external-sync:run with the same target and bounded maxEntries/maxRuntimeSeconds.
  3. Existing mirrored receipts are idempotent and skipped; failed or pending rows are eligible for retry.
  4. If a hard target/certificate error recurs, disable the target and keep the last error on the receipt row for operator review.

Manual exchange retry:

  1. If schedule export fails, regenerate the schedule from the sealed site after the certificate/signer or local selection issue is corrected.
  2. If relay processing fails before import-file creation, retain the schedule hash and relay failure report, then retry with the same schedule only when the target declaration and certificate validation still match.
  3. If sealed-site import validation fails, do not apply any receipts from that file. Store the failed import package hash and issue code, correct the relay or certificate problem, and request a new import file.
  4. If a duplicate import file is received after a successful import, applying it is idempotent for already stored target/local UUID receipts.

Audit Fields

Every schedule, relay, sync, and import event should record:

Common Failure Responses

FailureOperator response
installation_certificate_resolver_unavailableRegister or repair the Authority/Platform-backed installation-certificate resolver; Attestor must not mint its own exchange certificate.
transparency_exchange_signer_unavailableRegister or repair the regional crypto signer for the active installation profile.
certificate_expired_or_not_yet_validRotate or reactivate the installation certificate through Authority/Platform trust administration, then regenerate the schedule or import file.
certificate_revokedTreat the file as untrusted. Investigate the transfer and generate a new file after trust state is corrected.
certificate_untrustedReject the file and confirm the certificate chain/trust reference with Authority/Platform trust administration.
certificate_profile_mismatchConfirm the tenant or installation regional crypto profile and regenerate with a compatible provider.
unsupported_regional_algorithmRegenerate with a signer allowed by the active profile, for example GOST for a GOST profile or SM2/SM2-SM3 for an SM profile.
unknown_local_uuidConfirm the file belongs to this sealed site and the database has not been restored to an older snapshot.
local_entry_binding_mismatchReject the file. The receipt does not bind to the local entry UUID/index/digest.
file_digest_mismatch or checksums_mismatchTreat the package as tampered or corrupted. Re-export through controlled media.
signature_invalidReject the package and investigate the signer/certificate binding.
unsupported_target_declarationConfigure the relay with an approved external transparency target matching the schedule declaration.
target_unavailableUse connected-window retry later or keep mirror state mirror_pending.
external_transparency_sync_disabled (HTTP 409 on external-sync:run)Enable external sync and configure at least one enabled target before retrying connected-window sync.

Completion Evidence

An implementation is not complete until evidence shows both paths: