access-control
Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies, service accounts, user access, group…
Resource tags on Control Plane — labels that organize resources, trigger built-in cpln/ behaviors, and drive targeting. Use when the user asks about tags, labels, tagging, naming conventions, or resource protection.
$ npx -y skills add controlplane-com/ai-plugin --skill tag --agent claude-codeHow it fires
How this skill gets triggered: by you, by Claude, or both.
/tagContext preview
The summary Claude sees to decide when to auto-load this skill.
Resource tags on Control Plane — labels that organize resources, trigger built-in cpln/ behaviors, and drive targeting. Use when the user asks about tags, labels, tagging, naming conventions, or resource protection.
name: tag description: "Resource tags on Control Plane — labels that organize resources, trigger built-in cpln/ behaviors, and drive targeting. Use when the user asks about tags, labels, tagging, naming conventions, or resource protection."
Tags are **key-value labels** on almost every Control Plane resource (workload, GVC, identity, secret, policy, group, domain, image, volumeset, agent, ipset, org, mk8s, user, service account). They live in a top-level `tags:` map. A tag is three things at once: **metadata** for humans, a **selector** that policies/groups/GVCs/queries target, and — under the reserved `cpln/` namespace — a **switch** that turns on platform behavior the spec doesn't yet expose as a field.
| Capability | What a tag unlocks | Mechanism | |:---|:---|:---| | Dynamic RBAC | A policy `targetQuery` on `environment=production` grants on every match — **including resources created later** | **access-control** | | Dynamic group membership | A group `memberQuery` auto-enrolls users by tag (e.g. SSO provider) | **access-control** | | Dynamic placement | A GVC `locationQuery` picks locations by tag (e.g. `cpln/country`) instead of a fixed list | **query-spec** | | Fleet inventory & bulk ops | `cpln KIND query --tag tier=frontend` finds every matching resource to act on | **cpln** | | Built-in behaviors | Reserved `cpln/*` tags switch on features (protection, sticky sessions, mTLS, …) | see below | | Console organization | List columns, custom logos, saved groups, and the Query filter all read tags | see below |
The payoff is **retroactive and self-maintaining**: tag a new workload `environment=production` and every prod policy, group, and dashboard that queries that tag covers it automatically — no rule edits.
| Where | How | |:---|:---| | CLI, dedicated | `cpln KIND tag NAME --tag key=value` (repeatable); `--remove-tag key` drops one | | CLI, on create | `cpln KIND create ... --tag key=value` | | CLI, generic update | `cpln KIND update NAME --set tags.key=value` (kinds with no `tag` subcommand, e.g. `user`) | | MCP | The `mcp__cpln__create_*` / `update_*` tool for the kind accepts a `tags` object | | Manifest | A top-level `tags:` map, then `cpln apply -f FILE` |
cpln workload tag my-api --tag environment=production --tag team=payments cpln workload tag my-api --remove-tag team
**`=` guesses the type, `:` forces a string.** `--tag replicas=3` stores the number `3`; `--tag replicas:3` stores the string `"3"`; an empty value (`--tag key=`) stores `null`. This matters because queries are type-sensitive (see Gotchas).
Tags become leverage only when keys and values are **uniform** — a query for `environment=production` silently misses anything tagged `env=prod` or `Environment=Production`. Agree on a small, lowercase vocabulary up front:
| Key | Example values | Drives | |:---|:---|:---| | `environment` | `production`, `staging`, `dev` | RBAC scope, dashboards, promotion | | `team` / `owner` | `payments`, `platform` | ownership, on-call routing, group queries | | `tier` | `frontend`, `backend`, `data` | fleet ops, firewall / policy scope | | `app` | `checkout`, `billing-api` | grouping multi-workload apps | | `managed-by` | `terraform`, `console` | drift detection, IaC ownership |
Tag for the keys you will actually query; a tag nobody selects on is just decoration. Stay out of the `cpln/`, `syncer.cpln.io/`, and `firebase/` prefixes — those are platform-defined (below).
The `cpln/` namespace is reserved: don't invent your own keys under it, but **do** set the documented tags below to switch on behavior. They are the escape hatch for options not yet first-class fields.
**Any resource — deletion guard.** `cpln/protected=true` makes the platform refuse to delete the resource (any kind); remove the tag to delete. The MCP `delete_resource` and `cpln KIND delete` both fail until it's cleared. In the Console it's the lock switch next to **Actions**.
cpln workload tag WORKLOAD --tag cpln/protected=true # block delete cpln workload tag WORKLOAD --remove-tag cpln/protected # allow delete
**Workload behavior:**
| Tag | Value | Effect | |:---|:---|:---| | `cpln/timeoutSecondsOverride` | seconds (≤3600) | Raise the request timeout past the 600s ceiling | | `cpln/largeDisk` | `true` | Allocate a large ephemeral disk | | `cpln/tracingDisabled` | `true` | Turn off distributed tracing for this workload | | `cpln/publishNotReadyAddresses` | `true` | Route internal traffic to replicas before they pass readiness | | `cpln/discoverCrossGvcReplicas` | `true` | Discover replicas in other GVCs over mTLS | | `cpln/bypassProxyOutbound` | `true` | Skip the service-mesh proxy on outbound traffic | | `cpln/disableServiceMeshInboundPort` / `...OutboundPort` | port | Exclude one port from the service mesh | | `cpln/externalAuth*` | family | Route every request through an external authorization service (`...Address` required; see **workload-security**) | | `cpln/rateLimit*` | family | Enforce limits via an external rate-limit service (`...Address` required; see **cdn-rate-limiting**) |
BYOK / Direct-LB workloads add `cpln/disableServiceMesh`, `cpln/disableServiceMeshOutboundCIDR`, and `cpln/k8sClusterRole`.
**GVC — sticky sessions** (apply to every workload in the GVC): `cpln/sessionCookie` (cookie name) plus `cpln/sessionDuration` (a Go duration, e.g. `30m`).
**Domain:** `cpln/clientCertificateValidation=enabled` requires a valid client cert, i.e. mTLS (**domain**); `cpln/skipDNSCheck=true` skips DNS validation; `cpln/wildcard=true` enables a wildcard certificate.
Some tags are set *by the platform* and are read-only — their value is that you can **query** them:
| Tag | On | Use | |:---|:---|:---| | `cpln/city` / `cpln/country` / `cpln/continent` | location | Sele
Run containerized workloads across AWS, GCP, Azure, OCI, and your own hardware under one API.
Repo: controlplane-com/ai-plugin
Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies, service accounts, user access, group…
Audit trail and compliance on Control Plane. Use when the user asks about audit logs, who changed what, change tracking, audit contexts, writing custom audit…
Workload autoscaling and Capacity AI on Control Plane. Use when the user asks about scaling up/down, min/max replicas, scale-to-zero,…
CDN caching and request rate limiting for Control Plane workloads. Use when the user asks about CDN, Cloudflare, CloudFront, edge caching, rate limiting,…
Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI or CI/CD deploys, container…
Custom domains for Control Plane workloads. Use when the user asks to put a domain or subdomain in front of a workload, pick cname vs ns, configure routing or…