Skip to content

Links and References

Control Plane addresses resources by link. Pass a declared resource where a link is expected and the serializer emits the right one for its kind:

export const identity = new Identity({ name: "web-identity", gvc: "prod" });
export const web = new Workload({
name: "web",
gvc: "prod",
spec: { identityLink: identity }, // → //gvc/prod/identity/web-identity
});

The identity form is a documented silent failure. A policy binding written against //identity/NAME — which reads perfectly naturally, and is what most people guess — is accepted by the API and then ignored. The policy exists, the binding exists, and the permission is never granted. Only //gvc/GVC/identity/NAME works.

Passing the resource means never having to remember that. CPL013 catches it when you write the string by hand.

KindLink
GVC//gvc/NAME
Workload / Identity / VolumeSet//gvc/GVC/<kind>/NAME
Secret / Policy / Domain / IpSet//<kind>/NAME
Location/org/ORG/location/<provider>-<region>
This org’s image//image/NAME:TAG

cpln://secret/NAME.FIELD and cpln://volumeset/NAME are resolution URIs the container reads at runtime, not references between resources. They have no reference form, and CPL002 leaves them alone.

There is no template-time reference language in a Control Plane manifest, so a value known only after apply cannot be embedded in one. Referencing an attribute is a build error with an explanation rather than a manifest that silently contains the wrong thing.