Skip to main content

Data Classification Labels

Every asset (cog) in MOD carries a data classification label. Labels are a handling-and-routing mechanism: they decide how content may be used by MOD's AI features and, when export-control gating is turned on, which users and workers may touch it. MOD supports an operator's classification controls; MOD does not make a customer compliant with any framework, and setting labels does not by itself satisfy any control — the operator remains responsible for their own policy and assessment.

The label levels​

Labels are strictly ordered, low to high:

public < internal < confidential < restricted < CUI < EAR < ITAR

  • public, internal, confidential, restricted are the four internal handling tiers. New assets default to internal.
  • CUI (Controlled Unclassified Information) sits above the internal tiers: it carries marking and dissemination controls stricter than ordinary internal handling, while remaining "unclassified".
  • EAR (Export Administration Regulations) ranks above CUI: release to unauthorized persons can be an export violation even without a federal contract.
  • ITAR (International Traffic in Arms Regulations) is the top tier: defence articles and services with the strictest US-person rules.

Labels are stored on the asset (cogs.data_classification) and are matched case-insensitively against the seven known levels. An unrecognised stored label is never silently accepted or downgraded — it fails closed (treated as restricted), so a corrupt label cannot become a loophole.

How labels propagate to outputs​

When a workflow run produces an output asset, the output inherits the highest label among its inputs (max(input levels)). If the output was already hand-marked at a higher level, that marking is kept — propagation never silently downgrades an output.

Who can set and change labels​

  • Moves entirely within the four internal tiers (public … restricted) can be made by ordinary users.
  • CUI, EAR and ITAR are admin-gated: only a tenant admin or a platform admin may raise an asset into, lower it out of, or move it within that gated band. A non-admin attempt is refused with a 403.
  • Every label change is audited. Audit events: DATA_CLASSIFICATION_SET (raise) and DATA_CLASSIFICATION_LOWERED (lower), each recording the cog id, old and new level, and the actor.

What the labels enforce today​

1. Labelled data is never sent to external AI providers​

Any request that references restricted-labelled content — restricted, CUI, EAR or ITAR — is refused at the LLM-egress gate when the AI binding points at an external (non-local, non-managed) provider. This covers the support chat, the logs chat and the assistant; Node Wizard coverage is being added.

  • Governed by the platform setting labels.block_external_llm (group "labels", default on).
  • Local and MOD-hosted models are unaffected. A local or stack LLM endpoint (e.g. an Ollama instance, a LAN IP, or a stack alias) keeps serving labelled content; only provider URLs classified as external are refused.
  • The label block overrides any tenant external-LLM opt-in: a tenant that opted into external LLM use is still refused for labelled content.
  • The policy fails closed: if the settings read or the label lookup errors, the request is blocked rather than silently allowed.
  • Refusals are audited as LLM_EXTERNAL_BLOCKED_LABEL (details carry the surface, provider host and setting — never the prompt), and the API log shows a GY.C7: external LLM binding refused line.

2. Export-control US-person gating​

On top of the taxonomy, an optional US-person gate can be enabled with two platform settings (both default off, so nothing changes until the operator opts in):

  • compliance.export_control_enforced — master switch. When on, EAR/ITAR assets require a US person, and tasks whose inputs carry EAR/ITAR run only on US-person-operated workers.
  • compliance.cui_requires_us_person — additionally gates CUI assets (requires the master switch to be on as well).

The US-person attribute on a user is set only by a tenant admin or platform admin (PATCH /v1/users/{user_id}/export-control); non-admin and cross-tenant attempts are refused. With gating on, a non-US user reading or downloading an EAR/ITAR asset gets a 403, and a multi-file download is denied if any file in the set is EAR/ITAR labelled.

How to verify​

Check the audit trail (audit_events):

ActionEvent name
Label raised / loweredDATA_CLASSIFICATION_SET / DATA_CLASSIFICATION_LOWERED
External-LLM request refused by the label blockLLM_EXTERNAL_BLOCKED_LABEL
US-person attribute setUS_PERSON_FLAG_SET
Export-control read/download denialEXPORT_CONTROL_ACCESS_DENIED

Manual test steps for each path live in CORE/API/tests/MANUAL_TEST_DATA_CLASSIFICATION.md (GY.V2a / GY.V2b) and CORE/API/tests/MANUAL_TEST_GSEC_FIXES.md (GY.C7).

Watermark on labelled downloads (GY.V1b)​

An optional download watermark (three platform settings, all default off, so nothing changes until the operator opts in):

  • compliance.watermark_downloads_enabled — master switch. When on, an asset whose label is at or above the minimum is not handed out as a direct presigned URL: it is streamed through MOD's API with the watermark applied, and the delivery audit row records delivery_path = "watermark".
  • compliance.watermark_min_label — the lowest label that triggers it (default confidential).
  • compliance.watermark_unsupported_action — allow (default) delivers the original bytes for a content type this release cannot watermark and records metadata.watermark = "unsupported"; block refuses the delivery with a 403.

Two layers are applied to images (PNG / JPEG / WebP only in this release):

  • a visible tiled semi-transparent diagonal overlay naming the recipient, the UTC timestamp and the download id;
  • an invisible payload carrying the same download id in the luma channel as block-DCT sign bits with a checksum, so a leaked copy is self-identifying without trusting the client. It survives a lossless PNG round-trip and a JPEG quality-90 re-encode.

MOD supports leak tracing for an operator's own policy; MOD does not make a customer compliant with TPN or any other framework, and a watermark is a deterrent plus an attribution aid — not a control that satisfies one on its own.

The same three settings and the same label gate cover the other two delivery paths:

  • Share-link downloads (public embed run-surface output presign): a gated image output is not handed out as a presigned URL for the original blob — it is watermarked and re-published to a short-lived temp object that the presign points at. The payload identifies the share link (link id), not a user.
  • Zip / bulk export (folder, multi-cog and download-job archives): labelled image members are watermarked in place before the archive is written; non-image and unlabelled members pass through byte-identical.

Both paths still emit the existing delivery audit row. Fail-closed: if a label requires a watermark and it cannot be applied (e.g. a non-image under unsupported_action = "block", or an embedding that fails), the delivery is refused and the refusal is audited (metadata.watermark = "refused") rather than serving the unmarked file.

MOD supports leak tracing for an operator's own policy across every delivery path; MOD does not make a customer compliant with TPN or any other framework, and a watermark is a deterrent plus an attribution aid — not a control that satisfies one on its own.

Manual test steps: CORE/API/tests/MANUAL_TEST_GSEC_FIXES.md (GY.V1b and GY.V1c sections), including the one-liner that reads the invisible payload back out of a saved file.

Download and export marking (GY.V2 R-133)​

A label used to "die at the asset row" — the file you downloaded carried none of it. R-133 closes that gap for every content type (the image watermark above is a separate, additional mechanism). An asset is considered marked when its label is above public/internal; a corrupt stored label fails closed as ITAR.

  • Response headers. Every marked download, stream, zip export and share-link output carries X-MOD-Classification (the export-control banner for CUI/EAR/ITAR — CUI//<cat>, EAR (ECCN ..), ITAR — or the level name for higher internal tiers). CUI, EAR and ITAR additionally carry a short X-MOD-Handling caveat. Presigned S3 URLs cannot carry custom headers, so the marking rides on the API's JSON response and, for zips, inside the archive itself.
  • Zip marking file. A folder/multi-cog zip with at least one marked member gets a top-level CLASSIFICATION.txt listing the highest label in the archive and the per-member labels. Zips with no marked members are byte-identical to before.
  • Filename marking (opt-in). The platform setting labels.mark_download_filenames (default off) prefixes the saved filename of an export-controlled file with [CUI] , [EAR] or [ITAR] .
  • Propagation. Run outputs inherit the highest input label (as above); the inherited label then rides the output's own downloads, zips and share links — so the marking follows the data end-to-end.

MOD supports an operator's classification marking on egress; it does not make a customer compliant with any framework. Manual steps: CORE/API/tests/MANUAL_TEST_GSEC_FIXES.md (GY.V2 R-133 section).