Skip to content
Deployment
Skill

/tag

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.

From plugin
ai-plugin
1132 skills2 agents2 commands1 MCP

Claude Code

$ npx -y skills add controlplane-com/ai-plugin --skill tag --agent claude-code

SKILL.md

tag.SKILL.md
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 — Labeling, Built-in Behaviors & Targeting

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.

Why tags pay off

| 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.

Setting tags

| 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 | Each kind's `mcp__cpln__create_*` and `update_*` tool takes `tags` as a list of `{key, value}` pairs, as do `edit_group` and `edit_audit_context` (`?toolsets=full`); updates merge them into the existing tags, and `removeTagKeys` drops keys. Exceptions: `create_secret` and `update_org` take no tags, and `update_mk8s` takes no `removeTagKeys` | | 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).

A taxonomy that earns its keep

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).

Built-in tags that change behavior

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 wild

Read more
@controlplane-com
Ships withai-plugin

Run containerized workloads across AWS, GCP, Azure, OCI, and your own hardware under one API.

1132 skills2 agents1 MCP
Get the whole plugin

Stars on GitHub

Momentum

stars in total
11
Star history of controlplane-com/ai-plugin on GitHub, a chart by star-history.com

Other skills on ai-plugin.

cpln

cpln

Writes cpln CLI commands and workflows for Control Plane. Use when the user asks about cpln login, cpln apply, cpln workload, CLI…

create-app

create-app

Writes, builds, and deploys an app the user asks for in the chat, with no repository and no image yet. Use when the user asks to…

More skills from other plugins.

configuring-horizon

configuring-horizon

Use this skill whenever the user mentions Horizon by name in a Laravel context. Covers the full Horizon lifecycle: installing…

coolify10d66k
@coollabsio@coollabsioInstall Skill
vercel-cli

vercel-cli

Guides deployment, configuration, and troubleshooting with the Vercel CLI. Use when operating Vercel projects or resources…

vercel12d16k
@vercel@vercelInstall Skill
skypilot

skypilot

Use when launching cloud VMs, Kubernetes pods, or Slurm jobs for GPU/TPU/CPU workloads, training or fine-tuning models on cloud…

@skypilot-org@skypilot-orgInstall Skill
pinme

pinme

Use this skill when the user mentions "pinme", or needs to upload files, store to IPFS, create/publish/deploy websites or…

pinme8w3.8k
@glitternetwork@glitternetworkInstall Skill

Questions about tag.

Which coding agents can use tag?
tag installs in Claude Code, Codex, Cursor, Gemini CLI, GitHub Copilot, OpenCode and Windsurf with the skills CLI, using each agent's flag shown on this page. Flowy's auto-invocation, which fires a skill when your prompt matches, runs in Claude Code only.