| name | access-control |
| description | Primary skill for access control, policies, and RBAC on Control Plane. Use when the user asks about permissions, policies, service accounts, user access, group membership, bindings, who can do what, least-privilege, or IAM. |
Access Control & Policies โ Primary Skill
Tool availability: some MCP tools named here live in the full toolset profile โ if one is not advertised on this connection, tell the user to reconnect the MCP server with ?toolsets=full (or use the cpln CLI fallback). Reads and deletes work on every profile via the generic list_resources / get_resource / delete_resource tools.
A policy targets one resource kind and binds permissions to principals (users, groups, service accounts, workload identities). The common failure is a policy that exists but grants nothing โ a wrong targetKind, permission name, or principal link fails with no error โ so read the policy back after writing.
The model
| Layer | Scope | Controls |
|---|
| Billing-account roles | account-wide (set on the billing account, separate from org policies) | billing_admin, billing_viewer, org_creator โ none grant org-resource access |
| Org policies | per resource kind | all day-to-day access |
A caller is allowed an action when some policy on the resource's kind has a binding that lists that action (or a permission implying it) and names the caller โ or a group the caller is in.
Policy anatomy
A policy = one targetKind + a target scope + bindings.
kind: policy
name: app-secret-access
targetKind: secret
targetLinks:
- //secret/database-url
bindings:
- permissions: [reveal, use]
principalLinks:
- //gvc/production/identity/app-identity
Limits: bindings โค 50; principalLinks 1โ200 per binding; targetLinks โค 200. origin is read-only โ default (yours) or builtin (locked; see Built-ins).
Target scope (pick one): target: all (org-wide roles) ยท targetLinks (specific resources) ยท targetQuery (tag query โ see query-spec).
Valid target kinds: the targetKind enum accepts all 33 resource kinds, but only the 20 kinds with permission schemas (the ones get_permissions accepts) are meaningful targets: workload, secret, gvc, identity, image, org, policy, group, serviceaccount, user, volumeset, domain, location, ipset, mk8s, cloudaccount, agent, auditctx, quota, task.
Create vs update:
create_policy builds one binding from addPermissions ร (addUsers/addGroups/addServiceAccounts/addIdentities) โ providing only one side is an error (a binding needs both). It also requires exactly one target scope (targetAll / targetLinks / targetQuery). For several distinct bindings, use update_policy addBindings.
update_policy merges bindings (matched by exact permission set โ you can't extend a set) but replaces targets (targetLinks wholesale, removeTargetLinks incremental, targetAll โ mutually exclusive).
Permissions
get_permissions (kind) is the source of truth โ it returns the kind's exact permission list and its implication map. Confirm names with it before writing a policy; never hand-write them, and don't assume a kind only has create / delete / edit / view / manage.
Two traps that don't need a lookup:
manage implies every permission for a kind โ grant it only to true admins.
- Secret values need
reveal, not read โ the most common mistake.
Many kinds add non-obvious permissions beyond CRUD โ e.g. secret reveal/use, image pull, workload connect/exec.*, serviceaccount addKey, user invite/impersonate, mk8s clusterAdmin โ so pull the real set with get_permissions.
Principals
| Type | Link |
|---|
| User | //user/EMAIL |
| Group (preferred) | //group/NAME |
| Service account | //serviceaccount/NAME |
| Workload identity | //gvc/GVC/identity/NAME (GVC-scoped โ never //identity/NAME) |
An identity never belongs to a group, so authorize it only with a binding that names its exact link. At runtime the attached identity is the workload's API credential: calls from inside the workload with the injected CPLN_TOKEN against CPLN_ENDPOINT carry exactly the permissions policies grant that identity โ nothing more.
Groups
Members are users and service accounts only (โค 200). Bind policies to groups, not individuals.
- Create / edit:
create_group (name, memberLinks, memberQuery, identityMatcher); edit_group (addMemberLinks / removeMemberLinks โ read first with get_resource (kind="group")).
- Dynamic:
memberQuery matches users by tag query; identityMatcher matches identities by a jmespath/javascript expression.
Service accounts (non-human / CI/CD)
- Key:
add_key_to_service_account (serviceAccountName, keyDescription required, optional groupName) โ auto-creates the SA if missing and returns the key once (save it; lost = revoke + remint). create_service_account makes one with no key.
- Revoke:
update_service_account removeKeys: [NAME] (immediate). delete_resource (kind="service_account") revokes all keys.
- CI/CD auth: store the key as the
CPLN_TOKEN secret/env var โ the CLI uses it ahead of any profile (and works without one); don't pass --token on the command line (it leaks into logs). Full setup: gitops-cicd.
Users (IDP-backed)
- Invite:
invite_user_to_org (email, optional groupName).
- Read / remove:
get_resource (kind="user") / delete_resource (kind="user") take identifier (id or email); list_resources (kind="user") has an email filter. No create_user/update_user.
Built-ins (seeded per org)
| Resource | Name | Grants |
|---|
| Group | superusers | manage on every kind (creator auto-added) |
| Group | viewers | view on every kind |
| Service account | controlplane | platform-internal โ off-limits |
| Policies | superusers-KIND / viewers-KIND | origin: builtin, target: all |
- Grant org-admin by adding the principal to
superusers (or viewers for read-only) โ don't recreate admin policies.
- Built-in policies can't be created/edited/deleted; built-in groups can't be deleted, but their membership is editable (you can't remove yourself from
superusers).
- Any resource tagged
cpln/protected=true can't be deleted until untagged.
Common RBAC patterns
create_policy builds these; the cpln apply -f manifest is the policy-as-code equivalent for CI/CD.
- Org admin โ add to
superusers. Scoped admin โ one policy per targetKind with [manage].
- GVC developer โ
workload [connect, create, delete, edit, exec, view] + secret [create, delete, edit, reveal, use, view] on a developers group.
- Read-only โ add to
viewers.
- CI/CD SA โ
workload [create, delete, edit, view] + image [create, pull, view] + secret [use, view] on //serviceaccount/cicd-deployer.
- Workload identity secret access โ the anatomy example above; full flow in setup-secret (create identity, bind, attach via
spec.identityLink).
- Auditor โ
policy [view] + auditctx [view] on an auditors group.
Standard flow
get_cpln_rules (once per mutating session) and read this skill.
- Confirm the org (and gvc for identities) โ never guess.
get_permissions for the kind โ confirm permission names.
- Read current state:
list_resources (kind="policy") / get_resource (kind="policy") (+ get_resource kind="group" / kind="service_account").
- Smallest change; if destructive, confirm blast radius.
create_policy / update_policy (+ group / SA / user tools).
- Verify: read the policy back; confirm the bindings and target resolved.
Quick reference โ MCP tools
| Tool | Purpose | Key params |
|---|
mcp__cpln__get_permissions | Permissions + implications for a kind | kind |
mcp__cpln__list_resources (kind="policy") / get_resource (kind="policy") | List / read policies | name |
mcp__cpln__create_policy | Create a policy | name, targetKind, targetAll/targetLinks/targetQuery, addPermissions, addUsers/addGroups/addServiceAccounts/addIdentities |
mcp__cpln__update_policy | Update metadata, targets, bindings | name, addBindings/removeBindings, targetLinks/removeTargetLinks/targetAll, targetQuery |
mcp__cpln__delete_resource (kind="policy") | Delete a policy (destructive) | name |
mcp__cpln__list_resources (kind="group") / get_resource (kind="group") | List / read groups | name |
mcp__cpln__create_group | Create a group | name, memberLinks, memberQuery, identityMatcher |
mcp__cpln__edit_group | Add/remove members, update meta | name, addMemberLinks, removeMemberLinks |
mcp__cpln__delete_resource (kind="group") | Delete a group (destructive) | name |
mcp__cpln__list_resources (kind="service_account") / get_resource (kind="service_account") | List / read SAs (key metadata only) | name |
mcp__cpln__create_service_account | Create an SA (no key) | name, description |
mcp__cpln__add_key_to_service_account | Mint a key (auto-creates SA) | serviceAccountName, keyDescription, groupName |
mcp__cpln__update_service_account | Update meta / revoke keys | name, removeKeys |
mcp__cpln__delete_resource (kind="service_account") | Delete an SA (revokes all keys) | name |
mcp__cpln__list_resources (kind="user") / get_resource (kind="user") | List / read users | email / identifier |
mcp__cpln__invite_user_to_org | Invite a user by email | email, groupName |
mcp__cpln__delete_resource (kind="user") | Remove a user (destructive) | identifier |
CLI fallback (read the cpln skill first; verify with cpln <resource> --help): policy-as-code in CI/CD (CPLN_TOKEN + cpln apply -f), cpln RESOURCE permissions to list a kind's permissions, cpln policy access-report NAME to audit a policy.
Related skills
| Need | Skill |
|---|
Query language for targetQuery / memberQuery | query-spec |
| Org creation, billing, profiles, SSO | org-management |
| Audit trail of policy / access changes | audit-compliance |
| Full workload secret-access flow | setup-secret |
| Credential-free cloud access (AWS / GCP / Azure / NGS) | setup-cloud-access |
| Workload identities, private-network connectivity | native-networking |
Documentation