Core Concepts¶
This page serves as an introduction to the core concepts of Artficat Conduit (ARC).
The Order¶
The Order resource is the primary Custom Resource Definition (CRD) in the ARC (Artifact Conduit) system for declaring high-level artifact transfer operations. An Order specifies one or more artifacts to be processed, along with default source and destination endpoints. The OrderReconciler decomposes each Order into individual ArtifactWorkflow resources, which represent atomic artifact operations that can be executed independently.
The status map is populated by the OrderReconciler as ArtifactWorkflows are created. Each key is a truncated SHA-256 hash computed from the Order namespace, the artifact's type and spec, the ArtifactType generation, the source and destination endpoint names, the cron schedule, and the time of the last force reconciliation. A change to any of these creates a new ArtifactWorkflow at the next reconciliation. Changes to an Endpoint or its Secret do not affect the hash: updated Endpoint settings take effect only after a force reconciliation, while Secret contents are read each time a workflow runs.
See the spec documentation for details on how to define an Order.
The Endpoint¶
An Endpoint defines the configuration for artifact sources and destinations, including authentication credentials and usage constraints.
The Endpoint resource is a namespace-scoped configuration object that represents a location where artifacts can be pulled from or pushed to.
See the spec documentation for details on how to define an Endpoint.
Usage Modes¶
The usage field controls how an Endpoint can be used in artifact workflows:
PullOnly¶
The Endpoint can only be used as a source (srcRef) in ArtifactWorkflows. Attempts to use it as a destination will be rejected during validation.
Use Case: Public or third-party registries where ARC has read-only access.
PushOnly¶
The Endpoint can only be used as a destination (dstRef) in ArtifactWorkflows. Attempts to use it as a source will be rejected during validation.
Use Case: Internal registries in air-gapped environments where artifacts are pushed but never pulled.
All¶
The Endpoint can be used as both a source and a destination. This is the most flexible mode and is the default if usage is not specified.
Use Case: Internal registries that serve as intermediate storage or cache layers.
Status¶
An Endpoint reports what ARC has observed about it in status.conditions.
| Condition | Meaning |
|---|---|
Validated |
The referenced Secret exists and the Endpoint's type is accepted by some ArtifactType or ClusterArtifactType in a position its usage allows. |
Reachable |
The target answered. Any HTTP non 404 / 5xx response counts. The point of this condition is that something is listening. |
Authenticated |
True means the target demanded credentials and accepted the configured ones. ARC never sends credentials on the first request — only once the target's own response challenges for them. |
Ready |
A summary of the others, and the column kubectl get endpoints.arc.opendefense.cloud prints. |
Authenticated is Unknown rather than False when ARC cannot verify
credentials of that shape — an S3 Secret holding AWS_ACCESS_KEY_ID and
AWS_SECRET_ACCESS_KEY, for example; or the target served the probe request
without ever asking for credentials, so the configured ones were never exercised
(a public registry that ignores credentials entirely is the common case).
Unknown does not prevent an Endpoint from becoming Ready: it records
that ARC did not check, or had nothing to check, not that the check failed.
$ kubectl get endpoints.arc.opendefense.cloud
NAME CREATED AT REMOTE URL USAGE SECRET READY MESSAGE
registry 2d gcr.io PullOnly gcr-creds True
mirror 5h https://zot.local PushOnly zot-creds False credentials rejected (401)
When ARC probes¶
The connection test runs when there is a reason to believe the answer changed: on
creation, when spec changes, when the referenced Secret changes, when
validation starts resolving again after it had failed, and when the result is
missing from the status it was written to. By default there is no periodic
re-probe, so an Endpoint nobody touches produces no outbound traffic — see
Re-probing on a schedule to bound how stale a result
may become.
Upgrading from a version that kept this in memory costs one probe per Endpoint,
once: their status carries a result but not yet a record of what produced it.
To re-check on demand, set the force annotation to the current Unix timestamp:
$ kubectl annotate endpoints.arc.opendefense.cloud registry \
arc.opendefense.cloud/force-at="$(date +%s)" --overwrite
What the last probe ran against is recorded in status.probedGeneration,
status.probedSecretVersion and status.probedForceAt, next to the
status.lastProbeTime it produced. Those are what the decision above is made
from, so Reachable and its provenance always travel together: ARC never
re-probes because it forgot, and a restart or a leader failover does not
re-present every consumer's credentials.
Re-probing on a schedule¶
Reachability is a property of the world, not of the cluster: a target can go
down or come back without anything here to observe, so by default a Reachable
condition is only ever as fresh as the last reason to probe. Set
--endpoint-probe-ttl to bound that staleness — the controller then re-probes an
Endpoint whose result is older than the TTL, and nothing else changes:
controller:
args:
endpointProbeTTL: 15m
Expiry is spread across Endpoints by up to 20% of the TTL, derived from each
one's UID, so a set applied together does not come due together. The default is
0, which disables it.
Trusting an internal CA¶
The probe trusts the public CAs shipped in the controller-manager image. A
target with a certificate from an internal CA is therefore not verified, even
when the workflows trust it through a bundle their WorkflowTemplates mount.
Such an Endpoint reports Reachable=Unknown with reason
UntrustedCertificate, and Ready follows as Unknown. Other certificate
errors, like an expired certificate or a hostname mismatch, break the
workflows as well and are reported as Reachable=False with reason TLSError.
Give the controller-manager the same bundle the workflows use, e.g. the target
ConfigMap of a trust-manager Bundle:
controller:
trustBundle:
configMap: root-bundle
key: trust-bundle.pem
The ConfigMap must exist in the release namespace. With trust-manager this
means the namespace has to match the Bundle's namespaceSelector. The bundle
is added to the public CAs, it does not replace them. The controller-manager
reads it once at start, so restart it after the CA rotates.
A restart does not re-probe anything. Endpoints probed before the bundle was
set keep their verdict until the next probe: UntrustedCertificate, or
False/TLSError if they were probed by an ARC release before this reason
existed. Force a probe on all of them once the bundle is in place (see
When ARC probes), or let endpointProbeTTL catch up:
kubectl annotate endpoints.arc.opendefense.cloud --all-namespaces --all \
arc.opendefense.cloud/force-at="$(date +%s)" --overwrite
What Ready does not promise¶
The probe runs from ARC's controller-manager, using its network position and
its identity. The workflow pods that carry out an Order run under a different
ServiceAccount and may be subject to different egress rules. Ready=True is
therefore strong evidence that an Order will succeed, not a guarantee of it.
Operators should also note that the probe connects to a URL supplied by the
consumer. ARC refuses loopback and link-local addresses by default — replace that
list with controller.args.probeDenyCIDRs, or set it to an empty string to turn
the check off entirely — but a NetworkPolicy on the controller-manager Deployment
is the boundary to rely on.
The probe also reads the username/password keys of the Secret an
Endpoint references and sends them as Basic auth to the remoteURL the
Endpoint names — both chosen by whoever created the Endpoint. The first
probe is always sent anonymously, even if the Secret contains credentials.
Credentials are only sent if the initial anonymous probe responds with a
status indicating that authentication is required. This is to close the gap
between a public api that responds successfully no matter the credentials,
which can therefore not be checked on validity, and private endpoints that
require authentication and therefore validate the credentials by necessity.
create on endpoints.arc.opendefense.cloud must therefore be treated as
equivalent to get on Secrets in the same namespace: anyone who can
create an Endpoint can point it at a server they control and have that
Secret's credentials delivered to it. RBAC that grants Endpoint creation
without also granting Secret read is not a safe boundary. Egress
NetworkPolicy on the controller-manager is the control for where those
credentials may travel. See also
Secret Access.
The ClusterArtifactType and ArtifactType¶
The [Cluster]ArtifactType resource defines artifact processing capabilities within ARC by:
- Specifying validation rules for source and destination endpoint types
- Declaring parameters required by the underlying WorkflowTemplate
- Referencing an Argo WorkflowTemplate that implements the artifact processing logic
ClusterArtifactType resources are cluster-scoped configuration objects. ArtifactType resources are namespaced. Both establish the contract between ARC's orchestration layer and Argo Workflows' execution layer. When an ArtifactWorkflow is created with a specific type (e.g., oci), ARC queries the corresponding ArtifactType to validate endpoints and construct workflow parameters.
See the spec documentation for details on how to define an ArtifactType.
The ArtifactWorkflow¶
The ArtifactWorkflow resource represents a single, executable artifact operation within the ARC system. ArtifactWorkflows are the execution layer counterpart to the declarative Order resource - while an Order may specify multiple artifacts to process, each artifact is decomposed into an individual ArtifactWorkflow that can be independently executed by Argo Workflows.
Note
This resource type is created by the ARC Controller Manager and not to be used directly.
Integration with Argo Workflows¶
The ArtifactType acts as a bridge between ARC's declarative resource model and Argo Workflows' imperative execution model. When the ArtifactWorkflow reconciler processes a resource, it:
- Queries the ArtifactType by name (matching
ArtifactWorkflow.spec.type) - Validates source and destination endpoints against
rules.srcTypesandrules.dstTypes - Constructs workflow parameters by merging ArtifactType defaults with flattened artifact specifications
- Creates an Argo Workflow referencing the specified WorkflowTemplate
See the spec documentation for details on their specification.