Skip to main content
Version: Next

Private data-plane metadata

Publish the public DCAT dataset alongside a private envelope:

{
"dataPlaneId": "<registered management ID>",
"dataset": { "@type": "Dataset", "@id": "urn:example:dataset", "title": "Example" },
"dataplaneMetadata": {
"profiles": ["https://w3id.org/dspace-sig/profile/http-pull"],
"labels": [],
"properties": {
"baseUrl": "https://backend.internal/api",
"path": "/v1",
"authKey": "Authorization",
"authCode": "Bearer <backend-token>",
"contentType": "application/json"
}
}
}

The control plane stores this envelope privately. Profiles determine public distribution formats; labels restrict plane selection. Properties are opaque to the control plane and are validated by the selected plane. DPS start receives properties as metadata and labels unchanged. Catalogs and DSP messages do not contain private metadata. Management state reports only whether private configuration exists; it cannot identify credentials in an arbitrary plane's opaque contract.

Backend configuration stays in the control plane. Each data plane holds a snapshot for the life of a flow. Dataset edits affect new transfers; suspend/resume keeps the original snapshot and resume carries no metadata. Completion and termination clear the snapshot and access secret.

HTTP properties

The HTTP plane accepts plain keys and keys expanded with https://w3id.org/edc/v0.0.1/ns/. Conflicting plain and expanded values are rejected. baseUrl must be an HTTP(S) URL without embedded credentials.

PropertyBehavior
baseUrl, pathBackend URL path is base path + configured path + optional consumer path, with slashes normalized.
proxyPathForward the consumer sub-path.
proxyQueryParamsForward consumer query parameters.
proxyMethodForward consumer method; otherwise use method, default GET.
proxyBodyForward consumer body.
contentTypeSet Content-Type when a body is sent.
authKey, authCodeBackend header name and value; supply both together.
secretNameReserved; rejected until secret-store support exists.

Consumer paths must stay under baseUrl + path. Nested encoding of dots, slashes, backslashes or percent escapes is rejected because a backend could decode it differently. Ordinary encoded names, such as spaces, remain supported.

All four proxy flags default to true and accept booleans or strings "true" / "false". This differs from EDC's false defaults. The consumer's standard and configured compatibility authorization headers are removed before applying the backend credential. Credentials are redacted from request logs; response body previews are not logged.

TSG intentionally uses EDC's migration-bridge ownership model: HTTP backend metadata is required. This deviates from the DPS HTTP profile rule that metadata must not be required. The TCK fixture alone supplies fallback metadata; production has no fallback backend setting. Passing the TCK establishes signaling behavior under that fixture, not metadata-free HTTP transfers. JWT/JWKS and token renewal remain separate work.

Analytics properties

https://tsg.dataspac.es/profile/analytics-execution accepts an optional conformsTo string and provides a guarded execution endpoint. https://tsg.dataspac.es/profile/analytics-data requires source: {sourceId, path, fileName?}, with optional conformsTo. There is no inner type field. Unknown properties or invalid source contracts are rejected by the analytics plane.

Upgrade

Upgrade all services together. SQLite and PostgreSQL migrations map stored backend URLs, authorization headers, media types, and analytics source properties into the new envelope without logging values. Existing flows are cleared and active transfers terminated. Registration reset in the preceding migration requires dataset republication. The orchestration publisher migrates its private JSON in place. Restore a pre-upgrade database backup to roll back.

Dataset submissions supply dataplaneMetadata; the earlier assetConfig field has been removed. Stored rows are converted on upgrade: backendUrl becomes baseUrl, authorization becomes authKey: Authorization plus authCode, mediaType becomes contentType, and the old analytics types become profiles.