Nothing reaches into your cluster.
The connector dials out over HTTPS and holds the stream open. It applies Argo Workflows objects and refuses everything else. Runs can get their own namespace and service account, and both go when the run does.
Nothing reaches into your cluster
Every RPC is opened from inside your cluster. The connector dials out over HTTPS to one endpoint and holds the stream open. That is the entire network requirement. Nothing to open, nothing to allowlist.
- No inbound rule, no exposed port, no VPN, no bastion, no allowlisted source range.
- The only ports the connector listens on are health and metrics, and both are cluster-local.
outbound -> HTTPS, one endpoint, opened by the connector
inbound -> none
services -> 1, ClusterIP
ingress -> not rendered It applies workflow objects and refuses everything else
The connector will apply a Workflow, a WorkflowTemplate or a CronWorkflow. Anything else is refused at decode time, before it reaches the API server.
- The allowlist runs inside your cluster, not in dagweave.
- Two layers have to agree: the allowlist, and RBAC. A stock install can write Argo Workflows objects and its own CRDs, nothing else.
allowed -> Workflow, WorkflowTemplate, CronWorkflow
anything else:
"refusing to apply disallowed resource" The private key is generated in your cluster and stays there
At enrollment the connector generates an Ed25519 keypair from crypto/rand, inside your cluster, and writes it to a Secret in your namespace. dagweave is sent the public half, and stores that plus a SHA-256 hash of the one-time enrollment token.
- The chart ships no private key. The private half never leaves your namespace.
- One keypair per cluster, generated at install. Nothing is shared between clusters or between customers.
- The enrollment token is spent on first use, and we only store its hash.
- A dispatch only reaches the cluster that signed the request.
What is on the wire
Every call the connector makes carries a short-lived assertion it signs with that private key. dagweave looks up the public key registered for that connector and verifies the signature before doing anything else.
- A stolen assertion is worth one call. It is spent on first use, and expires after five minutes.
- The endpoint must be HTTPS. Only loopback addresses are exempt.
- The connector authenticates by signature. dagweave authenticates by TLS certificate, the way your browser does.
alg EdDSA (pinned by the verifier)
aud dagweave-connector
exp now + 5m (required, 30s leeway)
sub connector id (looked up, then verified) Logs and artifacts
The two take different paths. You choose where logs are stored. Artifacts stay in your object store, and dagweave fetches the ones it shows you with a short-lived URL your connector signs.
- Your log lines never pass through dagweave. Only a pointer to where they landed does.
- Artifact credentials are read from a Secret in your cluster. dagweave never holds a kubeconfig and never holds your object store keys.
logs -> console by default
or your own S3 / Loki / HTTP sink
or dagweave stores them for you
artifacts -> stay in your object store
dagweave GETs them with a presigned URL, 1h default Turn off what you don't need
The chart writes a rule per feature, and leaving a feature off means its rule is never written. features.artifacts is on by default, and it lets the connector read one named Secret in any namespace. That is what fetching an artifact takes. It cannot list and it cannot watch, so it has no way to go looking. Turn artifacts off and the rule is never created.
- Rules for its own CRDs, leader election and metrics are not tied to any feature.
- sources does not need that reach. It ships off, and turning it on gets it a list inside its own namespace, on the Secrets carrying its label.
- submit, status and logs work the same way. Disable one and its rules are never created.
- The connector re-checks each feature in code, against the connection serving the command. sources is the exception, checked once against the cluster config.
- The connector keeps itself up to date. There is no upgrade for you to schedule.
- The only thing it can rewrite is itself. Nothing else in the namespace is in reach.
submit: workflows, workflowtemplates, cronworkflows (RW)
status: workflows, workflowtemplates, cronworkflows (R)
configmaps (R), pod metrics (R)
logs: pods, pods/log (R)
artifacts: secrets, get, any namespace # on by default
sources: secrets, list, own namespace # off by default Nothing is left behind on the cluster
A run can get its own service account, its own namespace, or both. Whatever you give it is created when the run starts and deleted when it ends. Between runs there is nothing on the cluster with your name on it.
- The usual alternative is a permanent service account somebody made once and nobody has audited since.
- A namespace boundary is the one thing that reliably stops a workflow reading another team's Secrets and volumes.
- Cleanup is one delete. Kubernetes takes the pods, the volumes and everything the run created with it.
- A run gets what its group was scoped to, and nothing wider.
- The connector can only mint what your permission menu allows. That menu ships empty, and you are the one who writes it.
- If the connector is offline when a run ends, a sweep collects the namespace later. Cleanup does not depend on the run finishing cleanly.
dispatch -> namespace and service account created
run -> the workflow uses them, and nothing else can
finish -> namespace deleted, everything inside it with it
missed -> a sweep deletes what the run could not Your cluster runs every workflow
Your Argo Workflows controller executes the workflows. dagweave sends them there and reads status back. A running workflow needs nothing from us.
- Running workflows keep running. The Argo Workflows controller owns them, not us.
- Deployed CronWorkflows keep firing on schedule. The controller owns the timing.
- When the connector reconnects, dispatch and status resume. It catches up on what it missed.
Connect a cluster you already run.
dagweave is in early access. Leave an email and we will bring you on as we open it up.