generated: '2026-09-05' method: derived source: >- openapi/_original/calico-openapi.yml (components.schemas $ref graph), json-schema/calico-projectcalico.org_*-crd.yaml (published CRD openAPIV3Schemas), https://docs.tigera.io/calico/latest/reference/resources/ description: >- Entity graph for the Calico projectcalico.org/v3 resource API. Calico's model is unusual and worth stating plainly: almost nothing references another object BY ID. Resources bind to each other through Kubernetes LABEL SELECTORS evaluated at enforcement time. A NetworkPolicy does not hold a foreign key to the workloads it protects — it holds a selector string, and membership is whatever matches right now. Relationships below are therefore typed `selects` as well as the usual has_one/has_many. identity: key: metadata.name scope_field: metadata.namespace (namespaced kinds only) uniqueness: name is unique within its scope — cluster-wide for cluster-scoped kinds concurrency: metadata.resourceVersion (opaque string, optimistic concurrency) uid: metadata.uid (server-assigned, immutable) id_prefixes: none — Calico uses no prefixed identifiers; names are operator-chosen DNS labels envelope: note: >- Every resource is the same four-field Kubernetes envelope — apiVersion (const "projectcalico.org/v3"), kind (const, per type), metadata (ObjectMeta), spec. Status subresources exist on some kinds but are not in the OpenAPI. shared_schemas: - ObjectMeta - Status entities: - name: NetworkPolicy scope: namespaced spec: NetworkPolicySpec operations: [listNamespacedNetworkPolicy, createNamespacedNetworkPolicy, readNamespacedNetworkPolicy, replaceNamespacedNetworkPolicy, deleteNamespacedNetworkPolicy] crd: json-schema/calico-projectcalico.org_networkpolicies-crd.yaml key_fields: [order, tier, selector, serviceAccountSelector, types, ingress, egress] - name: GlobalNetworkPolicy scope: cluster spec: GlobalNetworkPolicySpec operations: [listGlobalNetworkPolicy, createGlobalNetworkPolicy, readGlobalNetworkPolicy, replaceGlobalNetworkPolicy, deleteGlobalNetworkPolicy] crd: json-schema/calico-projectcalico.org_globalnetworkpolicies-crd.yaml key_fields: [order, tier, selector, namespaceSelector, types, ingress, egress] - name: Rule scope: embedded embedded_in: [NetworkPolicySpec.ingress, NetworkPolicySpec.egress, GlobalNetworkPolicySpec.ingress, GlobalNetworkPolicySpec.egress] key_fields: [action, protocol, notProtocol, icmp, ipVersion, source, destination, http, metadata] enums: action: [Allow, Deny, Log, Pass] ipVersion: [4, 6] - name: EntityRule scope: embedded embedded_in: [Rule.source, Rule.destination] key_fields: [nets, notNets, selector, notSelector, namespaceSelector, ports, notPorts, serviceAccounts] - name: IPPool scope: cluster spec: IPPoolSpec operations: [listIPPool, createIPPool, readIPPool, replaceIPPool, deleteIPPool] crd: json-schema/calico-projectcalico.org_ippools-crd.yaml key_fields: [cidr, blockSize, ipipMode, vxlanMode, natOutgoing, disabled, disableBGPExport, nodeSelector, allowedUses] required: [cidr] - name: BGPPeer scope: cluster spec: BGPPeerSpec operations: [listBGPPeer, createBGPPeer, readBGPPeer, replaceBGPPeer, deleteBGPPeer] crd: json-schema/calico-projectcalico.org_bgppeers-crd.yaml key_fields: [node, nodeSelector, peerIP, peerSelector, asNumber, keepOriginalNextHop, password, sourceAddress, maxRestartTime, ttlSecurity] - name: BGPConfiguration scope: cluster operations: [listBGPConfiguration, readBGPConfiguration] crd: json-schema/calico-projectcalico.org_bgpconfigurations-crd.yaml note: >- READ-ONLY in this contract — the OpenAPI declares list and read but no create/replace/delete, even though the CRD is writable. Spec gap, recorded not papered over. - name: HostEndpoint scope: cluster spec: HostEndpointSpec operations: [listHostEndpoint, createHostEndpoint, readHostEndpoint, deleteHostEndpoint] crd: json-schema/calico-projectcalico.org_hostendpoints-crd.yaml key_fields: [node, interfaceName, expectedIPs, profiles, ports] note: No replaceHostEndpoint in the contract — create and delete only. Spec gap. - name: Profile scope: cluster operations: [listProfile, readProfile] note: >- READ-ONLY, and correctly so. Profiles are generated by Calico from Kubernetes namespaces and service accounts; they are not operator-authored. - name: NetworkSet scope: namespaced crd: json-schema/calico-projectcalico.org_networksets-crd.yaml in_openapi: false note: Named set of IP CIDRs referenceable from policy rules. Published CRD, absent from openapi/. - name: GlobalNetworkSet scope: cluster crd: json-schema/calico-projectcalico.org_globalnetworksets-crd.yaml in_openapi: false - name: Tier scope: cluster crd: json-schema/calico-projectcalico.org_tiers-crd.yaml in_openapi: false note: Ordered policy evaluation group. NetworkPolicySpec.tier points into it BY NAME. relationships: - from: NetworkPolicy to: Rule type: has_many via: spec.ingress[] and spec.egress[] binding: embedded - from: GlobalNetworkPolicy to: Rule type: has_many via: spec.ingress[] and spec.egress[] binding: embedded - from: Rule to: EntityRule type: has_one via: source binding: embedded - from: Rule to: EntityRule type: has_one via: destination binding: embedded - from: NetworkPolicy to: Tier type: belongs_to via: spec.tier binding: name-reference note: >- A rare true reference by name. If the named Tier does not exist the policy will not be admitted. - from: GlobalNetworkPolicy to: Tier type: belongs_to via: spec.tier binding: name-reference - from: HostEndpoint to: Profile type: has_many via: spec.profiles[] binding: name-reference note: The other true name reference — a list of Profile names. - from: BGPPeer to: Secret type: has_one via: spec.password.secretKeyRef binding: kubernetes-secret-reference note: >- Crosses OUT of the projectcalico.org group into core/v1 Secrets. An agent needs RBAC on Secrets in that namespace, not just on projectcalico.org, to configure an authenticated BGP peer. - from: NetworkPolicy to: WorkloadEndpoint type: selects via: spec.selector (label selector, evaluated at enforcement time) binding: label-selector note: >- NOT a foreign key. There is no operation that lists "the workloads this policy protects" — the set is whatever matches the selector at evaluation time, and it changes as pods come and go. - from: GlobalNetworkPolicy to: Namespace type: selects via: spec.namespaceSelector binding: label-selector - from: EntityRule to: NetworkSet type: selects via: selector / namespaceSelector matching NetworkSet labels binding: label-selector - from: IPPool to: Node type: selects via: spec.nodeSelector binding: label-selector - from: BGPPeer to: Node type: selects via: spec.nodeSelector and spec.peerSelector binding: label-selector - from: Profile to: Namespace type: derived_from via: Calico generates one Profile per Kubernetes namespace and service account binding: generated agent_notes: - >- There is no join, expand, or include parameter anywhere. Every traversal is a second request, and every selector-typed relationship cannot be traversed by API at all — you evaluate the selector against the objects yourself. - >- Before deleting anything, remember that no reversal exists (conventions/calico-conventions.yml). The blast radius of deleting a HostEndpoint or a GlobalNetworkPolicy is cluster-wide. coverage: entities_in_openapi: 9 entities_published_as_crd_only: 3 relationships: 14 note: >- The published CRD set is broader than openapi/ — 23 CRDs exist in the provider's repo against 7 resource kinds in the specs. json-schema/ holds 9 of them.