Skip to main content
Asset Portability moves institutional evaluation knowledge without flattening it into an unversioned file. An EvalGate portability bundle retains each asset’s canonical identity, exact content hash, dependencies, provenance, required scopes, calibration interpretation, and historical evidence. Use this control plane for governed organization transfers, environment promotion, backup and restore, or merger and reorganization work. The import never mutates destination state until an owner commits the exact plan returned by a persisted dry run.

Supported assets

Exports resolve these records from their native product stores. Imported assets remain visible in the portability workspace with both source and destination references; they do not replace the native source record that produced the bundle.

Permissions

The importer also compares every bundle and asset requiredScopes value with the actor’s current scopes. An import cannot grant or preserve a capability the committing actor does not hold.

Bundle identity and compatibility

Every new bundle declares:
The bundle hash is the SHA-256 digest of canonical JSON with bundleHash and signature removed. Each asset has a separate SHA-256 contentHash over canonical asset content. EvalGate verifies both layers before planning an import. dependencyOrder is a topological order, not a display hint. The importer rejects a missing required dependency, an expected dependency hash mismatch, or a cycle. Compatibility version 0 bundles are migrated to the current shape during validation. A bundle from a future unsupported compatibility version is rejected before any destination mutation.

Define the source-organization policy

The export policy travels inside the bundle hash and, when enabled, its signature:
  • classification is one of public, internal, confidential, or restricted.
  • allowCrossOrganization must be true when source and destination organizations differ.
  • allowedDestinationOrganizationIds narrows cross-organization import to explicit UUIDs. An empty list allows any destination only when cross-organization import is enabled.
  • requiresSignature makes an unsigned, invalidly signed, or untrusted bundle incompatible.
  • requiredScopes are checked in addition to each asset’s scopes.
Changing policy JSON after export changes the canonical bundle hash and invalidates the bundle.

Redact sensitive fields

Redactions use a canonical asset reference plus a JSON Pointer into that asset’s content value:
Available actions are: Each applied rule adds a redaction-manifest entry containing the asset reference, pointer, action, reason, and SHA-256 hash of the original value. The original value is not stored in the manifest. Asset and bundle hashes are computed after redaction, so an importer verifies the transferred representation exactly.

Configure signing keys

Export signing uses Ed25519 PEM keys configured on the EvalGate server. PORTABILITY_SIGNING_KEYS is a JSON array:
If publicKey is omitted, EvalGate derives it from the private key. Keep private keys in the deployment secret manager and rotate keyId values deliberately; the bundle embeds only the public key, key ID, algorithm, and signature. Before importing a signature-required bundle, a destination owner trusts the exact key:
Trust is organization-scoped. Matching only the key ID is insufficient: the public key and cryptographic signature must also match.

Export a governed bundle

Selectors identify native assets. Omit version to resolve the latest immutable version.
The response contains the stored export record and its complete bundle. Save the JSON without rewriting it. You can later retrieve the exact stored payload:
The download response includes X-EvalGate-Bundle-Hash. Compare it with the JSON bundleHash when moving the file through another system.

Preview an import

Every import begins with a dry run. Choose both a conflict policy and a reference policy explicitly:
The response persists an immutable plan with:
  • dryRunToken, bound to the complete request and destination state;
  • global compatible and partial results;
  • dependency order and a per-action count;
  • one planned target reference, target version, action, and compatibility result per asset;
  • structured issue codes such as SIGNER_UNTRUSTED, DEPENDENCY_MISSING, PRIVILEGE_WIDENING, REFERENCE_REMAP_MISSING, or CONFLICT.
Set allowPartial only when it is acceptable to commit compatible assets and retain explicit reject events for incompatible assets. With the default false, any incompatible asset blocks the commit.

Commit the exact plan

Add the returned token to the otherwise unchanged request:
EvalGate acquires an organization-scoped import lock and recomputes the plan inside the commit transaction. A changed bundle, policy, conflict choice, remap, partial setting, actor scope, signature trust state, or destination record makes the dry run stale and prevents mutation. The bundle record, committed import, portable assets, per-asset events, commit event, and audit log are written in one database transaction. If any write fails, none of them remain. Repeating a completed request with the same idempotency key returns the original import; reusing that key for a different request is rejected.

Verify imported evidence

List the organization workspace:
For each imported asset, verify:
  • canonicalRef and sourceCanonicalRef reflect the selected preserve or remap policy;
  • version is the planned destination version;
  • contentHash equals the exported asset hash;
  • dependencies point to the planned destination references;
  • provenance retains native source identifiers and the original native hash;
  • requiredScopes have not widened;
  • calibration assets retain rubricVersion, scoreScaleVersion, and mapping interpretation;
  • historicalEvidence contains the selected native reviews, decisions, runs, or snapshots.
Retrieve a specific import and its ordered event history with:

Failure behavior

Do not edit a bundle to work around an issue. Correct the source policy, redaction, dependency, destination conflict, signer trust, or actor authorization, create a new bundle when its contents change, and run a new dry run.