Reference Types
A reference is how a broker names the workload it wants a credential for. The broker asserts the reference and the Agent resolves it against a trusted node-local source before issuing anything. A reference type is therefore the unit of entitlement in BrokerPolicy: It decides which workloads a broker is able to name at all.
Two reference types resolve today, and their type URLs are the exact strings that go in a policy entry and on the wire:
| Reference type | Type URL |
|---|---|
| Kubernetes object | type.googleapis.com/spiffe.broker.KubernetesObjectReference |
| Process ID | type.googleapis.com/spiffe.broker.WorkloadPIDReference |
The two types differ in reach. A Kubernetes object reference names pods and nothing else. A process-ID reference names any process the Agent can see on its node, including host processes that belong to no pod. Grant the narrower type where it fits. See Broker Policy for how entitlements are written, including the * wildcard, which is a policy value only and never a reference a broker can send.
An unrecognized type URL is rejected with InvalidArgument: WORKLOAD_REFERENCE_INVALID: unrecognized reference type before any policy or attestation work happens.
Kubernetes object references
A Kubernetes object reference names a pod, by namespace and name, by UID, or by both. Pods are the only supported object: The reference must carry the exact literals pods as its plural and core as its group. No other built-in resource and no custom resource can be referenced, and a reference naming anything else is rejected with WORKLOAD_REFERENCE_INVALID.
Field rules:
| Rule | Detail |
|---|---|
| At least one of the key or the UID must be set | A reference with neither a namespace/name key nor a uid is rejected. |
name requires namespace | A pod name is only unique within a namespace, so a name without a namespace is rejected. |
| A UID alone is accepted | A reference carrying only a uid names the pod holding that UID, with no namespace or name required. |
| Both a name and a UID means both are checked | The Agent verifies that the named pod actually carries that UID, rather than trusting either field. |
Resolution verifies that a pod matching the reference exists in the kubelet's pod list for the Agent's own node, then attests that pod the same way the Workload API attests a caller. The Agent briefly polls the pod list rather than answering from a single snapshot, so a pod that is still being created is given a few seconds to appear. Because the pod list is the node's own, a broker can only resolve pods that are running on the node it is connected to.
This reference type requires Kubernetes workload attestation to be enabled for the cluster. Kubernetes attestation is the only source it has, so while attestation is disabled every Kubernetes object reference fails with Unavailable.
Resolution contributes pod-scoped attributes only, such as the pod's namespace, name, UID, service account, node, labels, and annotations. Container-level and process-level attributes are not available through this reference type.
Process-ID references
A process-ID reference names a process by its numeric PID. Two constraints apply to the PID a broker sends:
- It must be the workload's own process, not the sandbox process. In runtimes that run a separate sandbox or pause process per pod, the sandbox PID attests as the sandbox, not as the workload.
- It must be visible in the Agent's own PID namespace. Resolution reads facts about the process from the Agent's own view of
/proc, so a PID that is only meaningful inside another PID namespace does not resolve. The PID must be positive, and a reference with a zero or negative PID is rejected withWORKLOAD_REFERENCE_INVALID.
Resolution attests the process through the Agent's platform attestors: Kubernetes, Docker, Linux, and systemd. Each attestor that recognizes the process contributes its attributes, and the union of them is what the workload is attested as. JWT workload attestation is deliberately excluded from this path, because it reads a token the workload presents on its own connection, which a broker cannot present on another workload's behalf.
A process that belongs to no pod resolves normally. A systemd unit, a Docker container outside Kubernetes, or a plain host process is attested from whatever the other attestors produce. Kubernetes attestation is one of several attestors for this reference type rather than a requirement, unlike the Kubernetes object reference type above.
Which attestors are enabled therefore decides what a process-ID reference can be attested as. A process that no enabled attestor recognizes resolves with few or no attributes, which usually surfaces later as a template error at issuance time rather than as a resolution failure.
What resolution verifies, and what a failure means
Resolution is the step that decides whether a workload exists to be credentialed, and it runs on the first request and again on every re-verification of an open subscription. Three outcomes matter to a broker:
| Status | Meaning | Retryable |
|---|---|---|
InvalidArgument: WORKLOAD_REFERENCE_INVALID | The reference is malformed, or its type URL is not one of the two above. Validation runs before attestation, so the Agent never looked for the workload. | No. The same reference always fails. |
NotFound: WORKLOAD_NOT_FOUND | The reference is well formed, but no such workload exists on this node. For a Kubernetes object reference, no pod matching the namespace, name, or UID appeared in the node's pod list. For a process-ID reference, there is no such process, or the process has exited. | Only once the workload actually exists on that node. |
FailedPrecondition | The reference now resolves to a different workload than it first did. See Recycling protection. | No. Send a fresh reference for the new workload. |
The same statuses appear mid-stream, where they terminate the subscription instead of failing a single request. A broker that sees NotFound on an established stream is seeing the referenced workload go away, which is the expected end of a subscription's life.
Each resolution failure carries a message naming the specific field or workload at fault.
Recycling protection
A reference is a name, and names get reused. Both reference types pin the workload they first resolved to and re-check that pin on every re-verification, so a reference cannot quietly follow its name onto a replacement workload:
- Kubernetes object references pin the pod's UID at first resolution. A pod deleted and replaced by a same-named pod has a different UID, which is detected at the next re-verification. The stream terminates with
FailedPreconditionrather than serving the original pod's credentials to the replacement. - Process-ID references pin the process's identity at first resolution, using its start time and the user and group that own its
/procentry. A PID reused by a different process fails that comparison, so a recycled PID terminates the stream the same way. When the process does carry Kubernetes attributes, its pod UID and container name are pinned as additional checks.
A terminated stream here is the protection working, not a fault to be retried around. The broker's correct response is to subscribe again with a reference that names the workload it actually wants, which for a replacement pod means the replacement's own name or UID.
The identity a brokered workload receives
Resolvers never choose a SPIFFE ID. A resolver produces the workload's attested attributes, those attributes go to the Trust Domain Server in the issuance request, and the server renders the SPIFFE ID from the cluster's identity template. A brokered workload therefore receives exactly the identity it would receive through the Workload API, from exactly the same template.
What differs by reference type is the attribute set the template has to work with, since that follows from which attestors ran. The per-attestor attribute sets are listed with each workload attestation method. A template that requires attributes the reference type cannot produce fails issuance with an InvalidArgument template error, which reaches the broker rather than producing a credential under an unexpected SPIFFE ID. See An identity template that covers brokered workloads.