You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
PR #13986 replaces MLMD-backed artifact discovery with the native Artifact API, but artifact bytes are still read through a frontend-server route whose authority is assembled from caller-visible URI coordinates, an opaque providerInfo string, namespace-prefix heuristics, and optional per-namespace proxying.
That is not a complete replacement for MLMD's trusted ownership and storage context. The native API should expose an authenticated artifact-content contract keyed by artifact identity, with storage resolution and authorization performed from trusted server-side state.
Why this is a follow-up rather than a frontend patch in #13986
The current PR can and should close bounded frontend-server regressions: canonical namespace-prefix validation, view-role RBAC, query-safe links, request fan-out, and failure isolation. It cannot safely manufacture trusted storage provenance from browser-supplied values.
A durable fix requires a backend/API contract, authorization semantics, persisted or derivable trusted storage configuration, generated-client changes, and compatibility tests across S3, MinIO, GCS, custom roots, single-user, multi-user, and historical artifacts. Adding another query parameter or broadening the frontend server's credentials would enlarge the trust boundary and could turn compatibility failures into cross-tenant reads or credential use.
Verified gaps
1. Namespace-local Artifact rows are not sufficient ownership proof for custom roots
An authorized user can create/import an Artifact row in their namespace whose URI points at another location. An exact URI match in the caller's namespace therefore proves that the row is visible to the caller; it does not prove that centrally privileged object-store credentials may read the referenced bytes.
The private-artifacts/<namespace>/... convention provides independent ownership evidence for the standard root. Custom roots need equally trusted provenance or namespace-isolated credentials.
2. Opaque providerInfo crosses the browser/proxy trust boundary
Artifact URI query parameters are currently converted in the browser into provider JSON and forwarded through the central UI to the namespace artifact proxy. If accepted as authority, that JSON can select an endpoint and, in secret-backed mode, name credential Secret keys. Depending on the proxy service account's permissions, this permits unauthorized credential use/request signing and endpoint or SSRF control.
The browser may carry a hint, but it must not establish which endpoint or credentials the server is authorized to use.
For a stored URI such as s3://bucket/key?endpoint=..., the browser separates the query from the object key before calling the frontend server. The ownership validator reconstructs s3://bucket/key, so an exact native Artifact lookup cannot match the stored row. Strict ownership mode and custom-root proxy reads therefore reject legitimate records.
Reversing an opaque provider JSON string into a URI is not a safe canonicalization contract.
4. Namespace-prefix fallback is not bound to a trusted root
The fallback recognizes private-artifacts/<namespace>/... below any scheme/authority. If shared credentials can read another bucket or endpoint containing the same path, matching the namespace segment alone is not sufficient ownership evidence.
The fallback should be bound to a trusted configured root and retired for migrated records once #14029 is complete.
5. Custom-root credentials have no safe default multi-user path
The central UI correctly refuses to read tenant Secrets. The current alternative is the optional per-namespace artifact proxy, which is disabled by default and already documented as carrying security, maintenance, and scalability costs.
The replacement architecture needs a supported namespace-local credential path without requiring the browser to transport credentials/configuration or the central UI service account to read tenant Secrets.
providers.<provider>.default supplies storage settings and credentials only after a URI is admitted by the configured pipeline root or an explicit override; it is not authorization for arbitrary outside-root paths.
6. Artifact content lacks bounded transfer metadata
The native Artifact model does not provide a content-read operation with authoritative size, media type, range/peek semantics, or a server-enforced limit. Selected HTML/Markdown and legacy viewer sources may therefore be buffered in full before rendering.
Proposed API shape
The exact transport is open for design, but it should provide an artifact-ID-based operation such as:
a streaming GetArtifactContent/HTTP content endpoint;
a short-lived presigned URL minted after authorization; or
a server-side proxy with equivalent bounded streaming behavior.
The operation should:
Accept artifact identity, not caller-selected credentials.
Load the Artifact record and authorize access to its run/namespace.
Resolve storage configuration from trusted launcher/run/artifact provenance.
Bind the resolved scheme, authority, bucket, key, query configuration, and credential scope to that artifact.
Support custom roots without granting the central UI broad tenant Secret access.
Return or enforce media type, content length when known, byte ranges/peek, maximum preview size, and download disposition.
Preserve streaming and cancellation; do not buffer arbitrary objects in the API server.
Emit auditable errors that distinguish authorization, missing record, invalid trusted configuration, missing object, and transient provider failure without exposing secrets.
Security requirements
Never treat a caller-created Artifact row alone as authorization to use centrally privileged credentials for an arbitrary URI.
Never accept browser-supplied providerInfo, endpoint, region, Secret name, or Secret key as trusted authority.
Resolve tenant credentials inside the tenant's authorization boundary, or mint a narrowly scoped read capability after server-side validation.
Bind any prefix fallback to the configured scheme/authority/bucket/root and claimed namespace.
Protect against SSRF, DNS rebinding, redirects to untrusted hosts, credential forwarding, path traversal, encoded separators, and signed-query leakage.
Keep authorization fail-closed for custom roots and unknown provenance.
Ensure cache keys include artifact identity, authorization identity/context, namespace, content range, and configuration revision; do not share authorization results across tenants.
Acceptance criteria
A documented native artifact-content API is keyed by artifact ID and authorizes against trusted run/namespace ownership.
Standard roots, custom roots, S3, MinIO, and GCS work in single-user and multi-user deployments.
Browser-supplied provider JSON cannot select credentials, Secret keys, or an untrusted endpoint.
Query-bearing stored URIs retain one canonical identity from persistence through authorization and content resolution.
Feature description
PR #13986 replaces MLMD-backed artifact discovery with the native Artifact API, but artifact bytes are still read through a frontend-server route whose authority is assembled from caller-visible URI coordinates, an opaque
providerInfostring, namespace-prefix heuristics, and optional per-namespace proxying.That is not a complete replacement for MLMD's trusted ownership and storage context. The native API should expose an authenticated artifact-content contract keyed by artifact identity, with storage resolution and authorization performed from trusted server-side state.
Related:
Why this is a follow-up rather than a frontend patch in #13986
The current PR can and should close bounded frontend-server regressions: canonical namespace-prefix validation, view-role RBAC, query-safe links, request fan-out, and failure isolation. It cannot safely manufacture trusted storage provenance from browser-supplied values.
A durable fix requires a backend/API contract, authorization semantics, persisted or derivable trusted storage configuration, generated-client changes, and compatibility tests across S3, MinIO, GCS, custom roots, single-user, multi-user, and historical artifacts. Adding another query parameter or broadening the frontend server's credentials would enlarge the trust boundary and could turn compatibility failures into cross-tenant reads or credential use.
Verified gaps
1. Namespace-local Artifact rows are not sufficient ownership proof for custom roots
An authorized user can create/import an Artifact row in their namespace whose URI points at another location. An exact URI match in the caller's namespace therefore proves that the row is visible to the caller; it does not prove that centrally privileged object-store credentials may read the referenced bytes.
The
private-artifacts/<namespace>/...convention provides independent ownership evidence for the standard root. Custom roots need equally trusted provenance or namespace-isolated credentials.2. Opaque
providerInfocrosses the browser/proxy trust boundaryArtifact URI query parameters are currently converted in the browser into provider JSON and forwarded through the central UI to the namespace artifact proxy. If accepted as authority, that JSON can select an endpoint and, in secret-backed mode, name credential Secret keys. Depending on the proxy service account's permissions, this permits unauthorized credential use/request signing and endpoint or SSRF control.
The browser may carry a hint, but it must not establish which endpoint or credentials the server is authorized to use.
3. Query-bearing URIs lose exact ownership identity
For a stored URI such as
s3://bucket/key?endpoint=..., the browser separates the query from the object key before calling the frontend server. The ownership validator reconstructss3://bucket/key, so an exact native Artifact lookup cannot match the stored row. Strict ownership mode and custom-root proxy reads therefore reject legitimate records.Reversing an opaque provider JSON string into a URI is not a safe canonicalization contract.
4. Namespace-prefix fallback is not bound to a trusted root
The fallback recognizes
private-artifacts/<namespace>/...below any scheme/authority. If shared credentials can read another bucket or endpoint containing the same path, matching the namespace segment alone is not sufficient ownership evidence.The fallback should be bound to a trusted configured root and retired for migrated records once #14029 is complete.
5. Custom-root credentials have no safe default multi-user path
The central UI correctly refuses to read tenant Secrets. The current alternative is the optional per-namespace artifact proxy, which is disabled by default and already documented as carrying security, maintenance, and scalability costs.
The replacement architecture needs a supported namespace-local credential path without requiring the browser to transport credentials/configuration or the central UI service account to read tenant Secrets.
providers.<provider>.defaultsupplies storage settings and credentials only after a URI is admitted by the configured pipeline root or an explicit override; it is not authorization for arbitrary outside-root paths.6. Artifact content lacks bounded transfer metadata
The native Artifact model does not provide a content-read operation with authoritative size, media type, range/peek semantics, or a server-enforced limit. Selected HTML/Markdown and legacy viewer sources may therefore be buffered in full before rendering.
Proposed API shape
The exact transport is open for design, but it should provide an artifact-ID-based operation such as:
GetArtifactContent/HTTP content endpoint;The operation should:
Security requirements
providerInfo, endpoint, region, Secret name, or Secret key as trusted authority.Acceptance criteria
Test plan
Love this idea? Give it a 👍.