hcpctl
Guides users through hcpctl (PRM CLI) to discover, create, update, and manage 300+ enterprise infrastructure resource types including cloud accounts, Artifactory projects, SonarQube, Kafka, databases, networking, and Kubernetes.
Introduction
What is hcpctl?
hcpctl is the CLI for PRM (Platform Resource Manager) — UHG's internal infrastructure control plane. Think of PRM like Kubernetes but for enterprise infrastructure: it manages the lifecycle of 300+ resource types across cloud accounts, databases, networking, security, CI/CD tooling, and more.
What can you do with hcpctl?
With hcpctl you can create, read, update, and delete any registered infrastructure resource via YAML/JSON files. This includes:
- Cloud accounts (AWS, Azure, GCP) —
cloud-account.v2,dce.v1 - JFrog Artifactory projects and repos —
artifactory.project.v1 - SonarQube projects —
sonarqube.project.v1 - Kubernetes clusters and namespaces —
naas-v1,hcp-kubernetes-cluster-v1 - Databases (PostgreSQL, MySQL, MSSQL, CosmosDB, Snowflake) —
db-pgsql.v1,sdrp.common.database.v1 - Kafka clusters, topics, ACLs —
hcc-dataplatform-kafka-topic-v1 - Networking (VPCs, subnets, DNS, load balancers, firewalls) —
cas.managed-network.aws.v1 - Secrets and certificates —
secret.v2,certificate-v2 - API gateway —
stargate.api.v1 - Terraform Enterprise workspaces —
tfe.workspace.v1 - And much more — run
hcpctl kindsfor the full list
Key Concepts (read this first)
- Context — A named connection to a PRM environment (prod, stage, dev). You must create one before doing anything.
- Kind — A resource type registered in PRM (e.g.,
artifactory.project.v1). Each kind has a JSON Schema defining its spec. - Resource — An instance of a kind, identified by
{namespace}/{kind}/{name}. - Namespace — An organizational hierarchy in PRM (tied to resource groups/teams).
- Agent — A backend service that watches for lifecycle events and does the actual provisioning.
- Spec — The configuration payload for a resource. Schema is defined by the kind.
- Lifecycle — Resources go through states:
PendingCreate→Ready(orFailure).
How to discover what's possible
# List all resource types
hcpctl kinds
# Get the full JSON Schema for any kind's spec
hcpctl cat -o yaml system/kind/<kind-name>
# Find existing resources as templates
hcpctl ls <kind-name>
hcpctl cat -o yaml <namespace>/<kind>/<name>
The kind definition at system/kind/<kind-name> contains spec.schema — a full JSON Schema with required fields, types, validation patterns, enums, and examples. This is the authoritative source for building valid apply files.
Essential workflow
# 0. Install (one-time, Mac)
brew tap optum-eeps/prm-homebrew https://github.com/optum-eeps/prm-homebrew.git
brew trust optum-eeps/prm-homebrew
# Token generated from https://centraluhg.jfrog.io/ui/
export HOMEBREW_ARTIFACTORY_USER=<email used to generate token>
export HOMEBREW_ARTIFACTORY_TOKEN=<generated token>
brew install hcpctl
# 1. Setup (one-time)
hcpctl context create --uri https://prm.optum.com prm-prod
hcpctl context use prm-prod
hcpctl login
# 2. Discover
hcpctl kinds # What can I create?
hcpctl cat -o yaml system/kind/<kind> # What fields does it need?
# 3. Create
hcpctl apply -f my-resource.yaml --dry-run # Validate first
hcpctl apply -f my-resource.yaml # Apply
# 4. Inspect
hcpctl cat -o yaml <resourceId> # View resource
hcpctl priv <resourceId> # Check permissions
# 5. Modify
hcpctl patch -f my-patch.yaml # Partial update
hcpctl action <name> '<params>' <resourceId> # Trigger runtime action
# 6. Delete
hcpctl rm <resourceId>
Important sections in this document
| Section | What it covers |
|---|---|
| Logging In with hcpctl | Authentication methods (Azure MFA, token, OAuth2, env vars) |
| hcpctl apply | Creating and updating resources from YAML/JSON files |
| hcpctl patch | Partial updates using JSON Patch operations |
| hcpctl apply resource format | Full schema documentation, OpenAPI spec, and how to research schemas |
| Discovering PRM Resource Kinds | How to find available kinds, their schemas, and 300+ known kinds |
| hcpctl ls | Listing and filtering resources |
| hcpctl cat | Viewing resource details |
| hcpctl action | Triggering runtime actions on resources |
| hcpctl privileges | Checking RBAC permissions |
| Hcpctl Command Format | Global options and command structure |
Sources of truth (always verify against these)
- Live OpenAPI spec:
https://prm.optum.com/resource-api/v3/api-docs(no auth needed) - CLI source code:
https://github.com/optum-eeps/prm-hcpctl - Client library:
https://github.com/optum-eeps/prm-go-client-library - Kind schemas:
hcpctl cat -o yaml system/kind/<kind-name>(requires auth) - Official docs:
https://docs.hcp.uhg.com/platform-resource-manager/hcpctl(requires VPN)
Offical Documentation
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-mac-install
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-windows-install
- https://docs.hcp.uhg.com/platform-resource-manager/basic-context-creation
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-context
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-login
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-ls
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-remove
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-cat
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-apply
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-patch
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-action
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-privileges
- https://docs.hcp.uhg.com/platform-resource-manager/overview-hcpctl-commands
- https://docs.hcp.uhg.com/platform-resource-manager/hcpctl-env
Github Repo
https://github.com/optum-eeps/prm-hcpctl
prm.optum.com
https://prm.optum.com/resource-api/v3/api-docs
Overview HCPCTL
Getting Started with hcpctl – PRM Command Line Interface
Welcome! If you're new to PRM (Platform Resource Manager), hcpctl is the command-line tool that helps you interact with PRM in a fast and scriptable way.
🧭 What Is hcpctl?
hcpctl stands for Healthcare Platform Command Line Interface. It lets you:
Create resources View and list resources Delete resources You can use it on Mac, Linux, and Windows.
Previously known as techctl, this CLI has been rebranded to hcpctl. While techctl may still work, it is deprecated and no longer maintained.
🛠️ Why Use hcpctl?
While you can call PRM APIs using tools like:
curl Postman HCP Console Custom code hcpctl makes it easier to work with PRM directly from your terminal or scripts.
⚙️ Setup Steps
To get started with hcpctl, you’ll need to do two things:
1️⃣ Install hcpctl
Download / Install the latest version for your operating system.
Mac OS installation
xcode-select --install
brew tap optum-eeps/prm-homebrew https://github.com/optum-eeps/prm-homebrew.git
brew trust optum-eeps/prm-homebrew
# These environment variables must be set before you can brew install
# The token must be generated from https://centraluhg.jfrog.io/ui/
export HOMEBREW_ARTIFACTORY_USER=<email used to generate token>
export HOMEBREW_ARTIFACTORY_TOKEN=<generated token>
brew install hcpctl
Windows OS installation
Windows users installation These are instructions to install hcpctl in your Windows system.
Download hcpctl binaries
Download latest zipped windows version from here.
If you need to use a specific version of hcpctl, use this link template https://edgeinternal1uhg.optum.com:443/artifactory/glb-generic-uhg-loc/uhg-prm/hcpctl-windows/optum-hcpctl/v{current_version}/prm-hcpctl-SIGNED_{current_version}_windows_amd64.zip Replace the {current_version} value with the version you are looking for and download it from there.
Setup hcpctl
- Open PowerShell in administrator mode.
- Open the directory location of PowerShell
- Start PowerShell with elevated access
- The PowerShell window should open into your personal/MSID folder in the users directory. If it does not , please type 'cd c:\users{MSID}' (replace {MSID} with your MSID)
- In the PowerShell window type mkdir hcpctl and hit enter.
- Type cp '.\downloads\prm-hcpctl-SIGNED_{current_version}_windows_amd64.zip' .\hcpctl\ and hit enter.
- Navigate to the the hcpctl folder.
- Extract hcpctl into the folder.
Running hcpctl in Windows
There are two options for running hcpctl, local or pathed. Each method has advantages and disadvantages.
- Whichever method you choose, you will need to open a PowerShell window. You do not need to open the PowerShell window with admin access. However, if you intend to run other commands besides hcpctl, you may need admin access, so we recommend you use it.
If you are running hcpctl using the local method, navigate to the hcpctl folder ("cd hcpctl" in PowerShell). You will need to issue all hcpctl commands from this folder
- When you issue any hcpctl commands, you will need to preface them with "." Which is to say, instead of "hcpctl", you would call ".\hcpctl".
- The advantage to this method is that you do not need to assign pathing, you do not need to worry about pathing being reset, and you get used to making the local calls (typing ".").
- The disadvantages of this method are that you have to be in the correct/hcpctl folder, and you have to remember to include the extra header.
If you want to run hcpctl from any directory and without the header, you will need to create a path to the folder.
-
Open the Start menu, type "system", and click "Advanced System Settings".
-
Click the "Environment Variables" button oat the bottom of the tab.
-
In the "system Variables" section, scroll down to PATH, select that row, and click the Edit button.
-
Click the 'New' button and enter the new value c:\users[MSID]\hcpctl\ (replace [MSID} with your MSID).
-
Click Ok.
-
Reboot your system to refresh the path.
-
The advantage of this method is that you can run hcpctl from any folder in your system, and you do not need to add the local header.
-
The disadvantage for this method is that you must add to the path. And if any update reverts the path, you will have to repeat the process. Also, depending on what is installed on your system, your path may be too long to add more entries.
-
Once you have hcpctl installed and runnable, you can perform the configuration steps below.
Create contexts
Follow the instructions here to check hcpctl usage to create contexts and connect to the PRM instances.
Linux OS installation
Linux installation
These are instructions to install hcpctl on a Linux system.
Download hcpctl binaries
Download latest zipped linux version from here. Unzip the file into the path of your choice. You may need to make the file executable by running
chmod +x hcpctl
2️⃣ Create a Context
Before you can use hcpctl to interact with PRM (Platform Resource Manager), you need to create a context.
🧭 What Is a Context?`
A context is like a shortcut that tells hcpctl:
- 🌐 Which PRM environment to connect to like local, dev, stage, or prod.
- 🔐 What token or credentials to use
You can create multiple contexts for different environments and switch between them as needed.
🛠️ Example Context Creation Commands
Here are some common examples:
# Local development
hcpctl context create --uri http://localhost:8082 --token BOOTSTRAP prm-local
# Development environment
hcpctl context create --uri https://prm-dev.optum.com prm-dev
# Stage (non-production)
hcpctl context create --uri https://prm-stg.optum.com prm-stage
# Production
hcpctl context create --uri https://prm.optum.com prm-prod
📚 What’s Next?
Once installed and configured, you can start using hcpctl commands to interact with PRM.
Before using hcpctl, you have to login while the context is used. Note the token generated by the login has a expiration period.
hcpctl context use prm-prod
hcpctl login
Hcpctl Context Creation
To use `hcpctl`` you have to first setup a context. A context is telling hcpctl where you want to do your work. This can be any env of which PRM exists(prod,stage,dev...). Here are some example commands for commonly included contexts.
hcpctl context create --uri http://localhost:8082 --token BOOTSTRAP prm-local
hcpctl context create --uri https://prm-dev.optum.com prm-dev
hcpctl context create --uri https://prm-stg.optum.com prm-stage
hcpctl context create --uri https://prm.optum.com prm-prod
Next before using hcpctl, you have to login while the context is used. Note the token generated by the login has a expiration period.
hcpctl context use prm-prod
hcpctl login
🌐 Managing PRM Contexts with hcpctl context
In PRM, a context tells the hcpctl CLI which environment or instance of PRM you’re working with. Think of it like setting your workspace—once it’s set, all your commands will run against that environment.
🛠️ What is a Context?
A context includes things like:
- The URI (address) of the PRM manager
- An optional token for authentication
You can create, update, switch, or list contexts using the hcpctl context command.
📖 Get Help
To see all available options:
hcpctl context -h
## 📋 Common Subcommands
### 🔄 Switch Context
Use this to switch to a different PRM environment:
```bash
hcpctl context use <context-name>
This tells hcpctl to use the specified context for all future commands.
🆕 Create or Update a Context You can create a new context or update an existing one with:
hcpctl context create <context-name> --uri <manager-uri> [--token <auth-token>]
- --uri is required and tells hcpctl where to send commands.
- --token is optional and used for authentication if needed. Example:
hcpctl context create dev-env --uri https://prm-dev.example.com
##📜 List All Contexts To see all the contexts you’ve defined:
hcpctl context --list
✅ Show Current Context
To check which context is currently active:
hcpctl context --current
🧠 Summary for New Developers
| Command | Description |
|---|---|
| hcpctl context -h | Show help and usage info |
| hcpctl context use | Switch to a different context |
| hcpctl context create --uri | Create or update a context |
| hcpctl context --list | List all available contexts |
| hcpctl context --current | Show the current active context |
💡 Tips
- Always make sure you're in the right context before running commands.
- Use meaningful names for your contexts (e.g., prm-prod, prm-dev, sandbox).
- You can store multiple contexts and switch between them as needed.
🔐 Logging In with hcpctl – Beginner Guide
Before you can use hcpctl to interact with PRM (Platform Resource Manager), you need to log in. This step grabs a session token that allows you to make API calls. You’ll typically need to log in once per day, as tokens expire.
🧭 Basic Login
hcpctl login
hcpctl login -m <method>
🔐 Login Methods
You can choose different login methods depending on your setup:
1️⃣ Azure MFA Login (Default)
hcpctl login -m azure
A browser will open for you to log in.
If the above method fails, use:
hcpctl login -m azure-device-code
This is similar but you can use a browser from anywhere including your phone. Just go to https://microsoft.com/devicelogin and enter the given code when the command is run.
2️⃣ Token Login
hcpctl login -m token
# Please enter token: <token>
Paste in a token you already have. Useful if you retrieve tokens using another method.
3️⃣ OAuth2 Login
hcpctl login -m oauth -s https://api.uhg.com/.default --loginUrl https://api.uhg.com/oauth2/token
# Please enter ClientId: <your_client_id>
# Please enter ClientSecret: <your_client_secret>
You’ll be prompted for:
- ClientId
- ClientSecret
This method is used for Application Identities or automation.
If you have any Oauth2 login ClientId and ClientSecret, this method will work. As part of it being generic what is needed for this to work is scopes and a loginUrl. These are related to whatever service you are using to retrieve the token.
However some defaults are provided for Application Identities. The defaults are:
- scopes ->
https://api.uhg.com/.default - loginUrl ->
https://api.uhg.com/oauth2/token
4️⃣ Non-Interactive Login (Environment Variables)
hcpctl login -m env
Set the following environment variables before running the command:
export HCPCTL_LOGIN_METHOD=oauth
export HCPCTL_CLIENT_ID=<your_client_id>
export HCPCTL_CLIENT_SECRET=<your_client_secret>
export HCPCTL_TOKEN=<your_token> # if using token method
⚠️ MFA methods like azure are not supported in non-interactive mode.
📚 Help Command
To see all login options:
hcpctl login -h
✅ What Happens After Login?
Once logged in:
- Your token is stored and used for future hcpctl commands.
- You can now interact with PRM APIs using the CLI.
🔐 Reminder: Authentication alone isn’t enough. You also need RBAC (Role-Based Access Control) set up to access PRM resources.
If you need RBAC setup:
- Contact the Producer team that owns the resources.
- Or open an incident ticket or reach out via the PRM Teams channel.
Need help choosing a login method or troubleshooting token issues? Just ask!
📦 What is hcpctl ls?
The hcpctl ls command is like the ls command in Linux—it lists resources in PRM so you can see what’s available.
🔍 Basic Usage
Here are the most common ways to use hcpctl ls:
hcpctl ls
hcpctl ls <kind>
hcpctl ls -n <namespace> <kind>
<kind>refers to the type of resource (e.g., policy, namespace, etc.)-n <namespace>lets you filter by a specific namespace.
📄 Output Formats
You can choose how the results are displayed: JSON or YAML
hcpctl ls -o json
hcpctl ls -o yaml
Use this to get all the data about each resource.
Specific Fields Only
hcpctl ls -o json -f /spec/foo,/spec/bar
Use -f to limit the output to just the fields you care about.
📉 Limiting Results
Limit the Number of Resources
hcpctl ls --limit 100
By default, PRM returns up to 1000 resources. You can reduce that with --limit.
Count Only
hcpctl ls --count
This shows how many resources match your query—without showing the actual data. It’s useful for quick checks and isn’t blocked by RBAC.
📊 Sorting Results
hcpctl ls --sort asc
hcpctl ls --sort desc
Use --sort to organize results by creation time. Default is ascending (asc).
🧱 Listing Resource Groups (RGs)
See All RGs You Can Access
hcpctl ls -rg
Name NamespaceID
---- -----------
ind-001452922 sandbox/namespace/ind-001452922
ind-001693874 sandbox/namespace/ind-001693874
This shows the RG name and its resource ID.
See All Resources in an RG
hcpctl ls -rg <RG name>
Name Id
---- --
allow-access ind-001452922/policy/allow-access
child ind-001452922/namespace/child
child-2 ind-001452922/namespace/child-2
child-3 child/namespace/child-3
other child/policy/other
other child-3/policy/other
child-4 child/namespace/child-4
other child-4/policy/other
This lists everything inside a specific RG.
Tree View of Resources
hcpctl ls -rg <RG name> -t
Adds a tree view to show how resources are structured inside namespaces.
🧠 Advanced Commands
These are more powerful and flexible, but require a bit more understanding.
Attribute Selector
hcpctl ls -a /status/pendingAction
This lets you filter resources based on specific attributes.
JSON Attribute Selector
hcpctl ls --attributeSelector=’{"/status/pendingAction":null}’
This is a more advanced way to do the same thing using JSON.
Match Specific Values
hcpctl ls --attributeSelector=’{"/spec/foo":["bar"]}’
hcpctl ls -a /spec/foo=bar
These commands return resources where foo equals "bar".
📝 Attribute Selector Notes
[]→ empty, which means attribute must not existnull→ Attribute path must exist[1]or["abc"]→ Match a single value[1, 2, 3]or["a", "b", "c"]→ Match any of these values
✅ Summary
The hcpctl ls command is your gateway to exploring PRM. Start with basic listing, then try filtering, sorting, and attribute selectors as you get more comfortable.
🧹 Removing Resources in PRM with hcpctl rm
Welcome! If you're just getting started with PRM, this guide will walk you through how to remove resources using the hcpctl rm command.
Think of this as the "delete" command for PRM-managed resources.
🚀 Basic Command
hcpctl rm <resourceId>
This command removes (destroys) the resource you specify by its ID.
You can also remove multiple resources at once by separating them with spaces:
hcpctl rm <resourceId1> <resourceId2> <resourceId3>
🔍 Viewing PRM Resources with hcpctl cat
The hcpctl cat command is used to view detailed information about a single resource or resource group in PRM. Think of it like the cat command in Linux—it lets you "peek inside" a resource to see what’s going on.
🧪 Basic Usage
To view a resource:
hcpctl cat <resourceId>
Example:
hcpctl cat system/kind/role
This gives you a quick summary of the resource:
Name Kind Namespace Id State Age
---- ---- --------- -- ----- ---
role kind system system/kind/role Ready 4y2d
📄 Output Formats
You can view the full raw data of a resource in either YAML or JSON format:
hcpctl cat -o yaml <resourceId>
hcpctl cat -o json <resourceId>
💡 Tip: If you’re using JSON, tools like jq can help pretty-print the output for easier reading.
🧩 Additional Options
Here are some helpful flags you can use with hcpctl cat:
✅ --readyState
Shows the last known good state of the resource.
hcpctl cat --readyState <resourceId>
🌱 --children
Includes child resource IDs in the output. Requires -o to be used.
hcpctl cat -o yaml --children <resourceId>
💰 --chargeBack
Displays chargeback information for the resource.
hcpctl cat --chargeBack <resourceId>
🔐 --actions or -a
Lists all actions you’re allowed to perform on the resource, based on your RBAC permissions.
hcpctl cat -a <resourceId>
🗂️ Working with Resource Groups (RGs)
View a Resource Group
hcpctl cat -rg <rgName>
View Access Info for a Resource Group
hcpctl cat -rg --access <rgName>
Include User Info with Access
hcpctl cat -rg --access -lu <rgName>
You can also include specific user details:
hcpctl cat -rg --access -lu --includeName --includeEmployeeId --includeEmail <rgName>
| Option | What it adds |
|---|---|
--includeName or --in | User names |
--includeEmployeeId or --iei | Employee IDs |
--includeEmail or --ie | Email addresses |
--includePending or --ip | Pending users |
🧠 Summary for New Developers
| Command | Description |
|---|---|
hcpctl cat <id> | View a resource summary |
hcpctl cat -o yaml/json <id> | View full resource in YAML or JSON |
hcpctl cat --readyState <id> | View last known good state |
hcpctl cat --children <id> | Include child resources |
hcpctl cat --chargeBack <id> | Show chargeback info |
hcpctl cat -a <id> | Show allowed actions |
hcpctl cat -rg <name> | View a resource group |
hcpctl cat -rg --access -lu <name> | View RG access with user info |
🚀 Creating or Updating Resources with hcpctl apply
The hcpctl apply command is the main way to create a new resource or update the entire resources in PRM. You’ll use it when you have a resource definition file (usually in YAML or JSON format) and want to apply it to the PRM system.
If you only need to update specific parts of a resource in PRM—without replacing the whole thing, you should use the hcpctl patch command.
📄 Basic Usage
hcpctl apply -f <filepath>
-for--fileis required.<filepath>is the path to your resource file.
This command will:
- Create the resource if it doesn’t exist.
- Update the resource if it already exists.
You’ll get a report showing which resources were successfully applied and which failed.
🧪 Dry Run (Validation Only)
Want to test your file before actually applying it? Use --dry-run:
hcpctl apply -f <filepath> --dry-run
This checks for errors and formatting issues without making any changes.
🔁 Force Event Trigger
Sometimes you want to trigger the resource’s update lifecycle even if nothing has changed. Use --force-event:
hcpctl apply -f <filepath> --force-event
This is useful when you want to reprocess a resource even if its content hasn’t changed.
🧬 Apply Spec Only
If you only want to update the spec (the configuration part) and not create any new resources, use:
hcpctl apply -f <filepath> --apply-spec-only
This is a safe way to update existing resources without accidentally creating new ones.
⚠️ Hard Update (Advanced)
hcpctl apply -f <filepath> --hard-update
This is a special-use option that updates a resource without triggering its lifecycle (i.e., it won’t go into a pending state or notify agents).
🔒 Note: This requires special permissions and is typically used by the PRM product team for support purposes. It’s blocked for general users by RBAC.
✅ Summary for New Developers
| Option | What it does |
|---|---|
-f | Required. Specifies the resource file to apply |
--dry-run | Validates the file without applying it |
--force-event | Forces an update even if the resource hasn’t changed |
--apply-spec-only | Updates only the spec; doesn’t create new resources |
--hard-update | Updates without triggering lifecycle (restricted use) |
💡 Tips
- Always start with
--dry-runto catch issues early. - Double-check your file paths and formatting.
- Use
--apply-spec-onlywhen you’re sure the resource already exists. - Avoid
--hard-updateunless you’ve been instructed to use it.
🩹 Updating Specific Fields with hcpctl patch
The hcpctl patch command lets you update specific parts of a resource in PRM—without replacing the whole thing. This is useful when you only want to change a few attributes.
🧾 What You Need
To use hcpctl patch, you’ll need a patch file (usually in YAML format) that defines:
- The resource ID you want to update
- The section of the resource you’re targeting (like status, spec, etc.)
- The patch operations you want to perform
🧪 Example Patch Files
Status Patch
id: my-meal-plans/wfd.meals.v1/saturday
endpoint: status
patch:
- op: add
path: /status/pendingAction/context
value:
some-nbr-1: 54321
myArray:
- array-item-1
- array-item-2
- op: add
path: /status/pendingAction/onComplete/success/keepContext
value: true
- op: replace
path: /status/pendingAction/agents/wfd-agent
value: Resolved for me!
Spec Patch
id: my-meal-plans/wfd.meals.v1/saturday
endpoint: spec
patch:
- op: replace
path: /spec/number_of_meals
value: 10
# add item to end of list
- op: add
path: /spec/health_preferences/-
value: vegan
# remove specific item from list (index 1)
- op: remove
path: /spec/calorie_percentages/1
What’s Happening Here?
op: The operation type (add,replace,remove, etc.)path: The exact field you want to updatevalue: The new value to apply
🚀 Running the Patch
Once your patch file is ready, apply it with:
hcpctl patch -f <your-patch-file>.yaml
🧠 Summary for New Developers
| Concept | Description |
|---|---|
patch file | A YAML file that defines what to update |
id | The full ID of the resource you want to patch |
endpoint | The section of the resource to update (e.g., status) |
op | The operation type: add, replace, remove, etc. |
path | The exact field to change |
value | The new value to apply |
💡 Tips
- Always double-check your
pathandvalueformatting. - Use
addto insert new data,replaceto update existing data. - You can patch multiple fields in one file.
- If you’re unsure, ask a teammate to review your patch file before applying.
🛠️ PRM Runtime Actions: Getting Started with hcpctl action
In PRM (Policy Resource Manager), resources can have actions you can perform on them. This guide walks you through how to discover and trigger those actions using the hcpctl CLI tool.
🔍 Step 1: Discover Available Actions
To see what actions are available for a specific resource, run:
hcpctl cat --actions <resourceId>
Replace <resourceId> with the actual ID of the resource you’re working with. This will list all the actions that can be triggered on that resource.
🚀 Step 2: Trigger an Action
Once you know the action name, use the following format to trigger it:
hcpctl action <actionName> <parameters> <resourceId1> <resourceId2> ...
<actionName>: The name of the action you want to perform.<parameters>: Optional. A JSON string with key-value pairs.<resourceId>: One or more resource IDs the action should apply to.
Example
hcpctl action updateStatus ‘{"status":"active"}’ res-123 res-456
This runs the updateStatus action with a parameter to set status to "active" on two resources.
🧪 Step 3: Dry Run (Optional)
Want to test the command before actually running it? Add --dry-run:
hcpctl action updateStatus ‘{"status":"active"}’ res-123 --dry-run
This checks if the command is valid without making any changes.
🧠 Tips for JR Developers
- Always start with
hcpctl cat --actionsto understand what’s possible. - Use
--dry-runwhen you’re unsure—it’s safe and helps you learn. - Parameters must be in valid JSON format. Use double quotes (
") around keys and values.
📘 hcpctl privileges
The hcpctl priv command helps you check what privileges you (or another user) have on a resource in PRM. It uses PRM’s RBAC (Role-Based Access Control) and ABAC (Attribute-Based Access Control) systems. You can use it to:
- See what actions you’re allowed to perform on an existing resource
- Check what privileges you’d have on a non-existent resource (RBAC only)
🔧 Basic Usage
hcpctl priv <resourceId> | jq
This will return a list of privileges in a readable format using jq.
🧾 Example Output
{
"create": "no",
"decrypt": "no",
"destroy": "no",
"hard-delete": "no",
"hard-update": "no",
"list": "yes",
"migrate": "no",
"read": "yes",
"update-children": "no",
"update-parent": "no",
"update-spec": "no",
"update-status": "no",
"write": "no"
}
Each field shows whether you’re allowed (yes) or not allowed (no) to perform that action.
🖥️ Output Format
You can choose how the output is formatted:
hcpctl priv -o <yaml|json> <resourceId>
-o yaml→ Output in YAML format-o json→ Output in JSON format
👤 Check Another User’s Privileges
You can check privileges for another user by using their MSID:
hcpctl priv -u <msid> <resourceId>
-uor--usernamelets you specify the user<msid>is the user’s MS Domain ID
✅ Summary
| Flag | Description |
|---|---|
<resourceId> | The ID of the resource you’re checking |
-o <yaml|json> | Format the output (yaml or json) |
-u <msid> | Check privileges for another user (by MSID) |
📘 Hcpctl Command Format
hcpctl is the CLI tool for interacting with PRM. All commands follow a consistent structure:
hcpctl <global-options> <command> <command-options> <operands>
If the command has subcommands, the format looks like this:
hcpctl <global-options> <command> <command-options> (<subCommand> <subCommand-options> ...) <operands>
✅ Examples
Basic Command
hcpctl --config /path/to/config ls -n someNamespace someKind
Command with Subcommand
hcpctl --config /path/to/config context create --token someToken my-context
🔍 Need Help?
You can get help for any command by adding -h:
hcpctl -h
or
hcpctl ls -h
🌍 Global Options
Global options can be used with any command. They are not command-specific.
version
Print the current version of hcpctl:
hcpctl --version
help
Display the help screen:
hcpctl --help
config and azureConfig
Specify custom config paths instead of defaults:
hcpctl --config /my-config/path
context
Use a specific context instead of the default:
hcpctl --context my-context
forceLogin
Force an interactive login instead of silent token refresh:
hcpctl --forceLogin
This is useful if:
- Non-interactive login fails
- Token expiration causes errors
After login, the command runs immediately.
✅ Summary Table
| Option | Description |
|---|---|
--version | Show current version of hcpctl |
--help | Display help info |
--config | Use a custom config file |
--azureConfig | Use a custom Azure config file |
--context | Switch to a specific context |
--forceLogin | Force interactive login and run command |
📘 hcpctl env
The hcpctl env command shows your current environment settings for the hcpctl tool. These settings tell hcpctl which PRM environment you’re connected to and what token is being used.
✅ What Does It Do?
When you run:
hcpctl env
You’ll see output like this:
export PRM_CONTEXT=prm-perf
export PRM_TOKEN=<TOKEN>
export PRM_URI=https://prm-perf.optum.com
🔍 What Each Value Means
PRM_CONTEXT— The name of the environment you’re working in (e.g.,prm-perf,prm-dev,prm-prod).PRM_TOKEN— Your authentication token for PRM. (Hidden for security reasons — never share this!)PRM_URI— The base URL for the PRM environment.
🛠 Why Is This Important?
These values tell hcpctl:
- Which PRM environment to use
- How to authenticate your commands
- Where to send API requests
If something looks wrong (e.g., wrong context or URL), you may need to switch environments or refresh your token.
hcpctl apply resource format
⚠️ Sources of Truth
The resource format is defined in multiple authoritative sources. Always verify against the latest before generating apply files:
- OpenAPI Spec (live) —
https://prm.optum.com/resource-api/v3/api-docs(OpenAPI 3.1.0, current version 5.2.4) - Go client library —
optum-eeps/prm-go-client-libraryfor struct definitions - CLI source —
optum-eeps/prm-hcpctlfor how the CLI parses and sends resources - Never assume the format is unchanged — new fields or validations may be added in any release
🔍 How to Research the Current Schema
Step 0: Fetch the OpenAPI spec (fastest, most authoritative)
The PRM API exposes its OpenAPI spec publicly (no auth required):
curl -s https://prm.optum.com/resource-api/v3/api-docs | python3 -m json.tool > /tmp/prm-api-docs.json
This gives you the complete API contract including:
- All endpoint paths and HTTP methods
- Request/response schemas with validation rules (patterns, required fields, enums)
- Field descriptions and examples
- Read-only vs writable field distinctions
Step 1: Check the ResourceDocument struct
gh api repos/optum-eeps/prm-go-client-library/contents/prm/resource.go --jq '.content' | base64 -d
This file defines how resources are parsed. Key details:
- Resources are unmarshalled via
NewResourceFromYaml()orNewResourceFromJson() - YAML is first converted to JSON internally (
yaml.YAMLToJSON) - The
standardstruct defines the required top-level shape:kind+metadata
Step 2: Check the Metadata struct
gh api repos/optum-eeps/prm-go-client-library/contents/prm/types/resource.go --jq '.content' | base64 -d
This file defines the Metadata struct with all field names, types, and JSON tags. It also defines ResourceID validation (must be {namespace}/{kind}/{name}).
Step 3: Check the apply command parsing
gh api repos/optum-eeps/prm-hcpctl/contents/cli/commands/apply.go --jq '.content' | base64 -d
This shows:
- How files are read (
internal.ApplyFileOrURL) - How multi-document YAML is handled (
yq.UnmarshalList) - What flags affect behavior (
--dry-run,--apply-spec-only,--force-event,--hard-update)
Step 4: Check resource parsing internals
gh api repos/optum-eeps/prm-hcpctl/contents/cli/internal/resource.go --jq '.content' | base64 -d
This shows ApplyFileOrURL() which handles both local files and GitHub URLs, plus the ResourceGroup apply format.
📐 PRM Resource Document Structure (ResourceDto)
From the OpenAPI spec (Prm-resource-api API v5.2.4) and confirmed by Go source analysis:
Required fields: kind, metadata (with name + namespace), spec
kind: <kind-name>
metadata:
# --- Required fields ---
name: <string> # Resource name
namespace: <string> # Parent namespace
# --- Optional writable fields ---
labels: # Key-value string pairs for categorization
key: value
annotations: # Key-value string pairs for metadata
key: value
parent: <namespace>/<kind>/<name> # Parent resource ID
displayName: <string> # Human-readable name/alias
askId: <string> # ASK ID of chargeback resource group
groupName: <string> # Name of chargeback resource group
# --- Cloud-specific (optional) ---
isProduction: false # Is this a production resource
platformLocation: <string> # Region (e.g., "us central")
operationalEnvironment: <string> # Environment name
cloudServiceProvider: <string> # Cloud provider name
platformIdentifier: # Cloud resource identifiers
cloudId: "01234567"
subscriptionId: "9876abc543def"
# --- System-managed (read-only, do NOT set on apply) ---
# id, offset, uuid, event, version,
# created, createdBy, updated, lastUpdatedBy, deleted, deletedBy
spec:
# Kind-specific configuration payload (JsonNode - any valid JSON/YAML)
# Structure varies entirely by resource kind
# Use `hcpctl cat -o yaml <existing-resource>` to see examples
# status: (read-only, system-managed, do NOT set on apply)
# children: (read-only, system-managed)
Naming Validation Rules (from OpenAPI patterns)
| Field | Pattern | Example |
|---|---|---|
kind | ^[a-z][a-z0-9]*([.-][a-z0-9]+)*$ | sample-kind, aws.ec2.instance |
metadata.name | lowercase alphanumeric with dots/dashes, starts with letter | my-resource, app.v1 |
metadata.namespace | [.] or ^[a-z][a-z0-9]*([.-][a-z0-9]+)*$ | sample-namespace |
ResourceID Format
Resource IDs follow a strict 3-part format validated by ResourceID.Validate():
{namespace}/{kind}/{name}
Examples:
system/kind/rolemy-namespace/policy/allow-accesssandbox/namespace/ind-001452922
Multi-Document Files
Apply files can contain multiple resources separated by ---:
kind: policy
metadata:
namespace: my-namespace
name: allow-read
spec:
actions: [read, list]
---
kind: policy
metadata:
namespace: my-namespace
name: allow-write
spec:
actions: [write, update-spec]
The CLI uses yq.UnmarshalList() to parse all documents and applies them sequentially.
Remote Files
Apply supports GitHub URLs directly:
hcpctl apply -f https://github.com/optum-eeps/prm-consumer-namespace-agent/blob/main/rbac-setup/apps-create-first.yaml
Requires HCPCTL_GITHUB_TOKEN environment variable for authentication.
📐 Resource Group Apply Format (ResourceGroupDto)
From the OpenAPI spec. Required field: type only.
Resource Groups use a different structure (applied with hcpctl apply -rg -f):
# Create a new Resource Group (name is empty)
type: APP # Required: IND | APP | STD
askId: <ask-id> # For APP/STD types
msId: <msid> # For IND types
name: <string> # Pattern: ^[a-z][a-z0-9]*([.-][a-z0-9]+)*$
description: <string>
parentNamespace: <string>
alias: <string> # Friendly name (not unique)
displayName: <string> # Friendly display name
labels:
component: infrastructure
mode: auto-approve
annotations:
stage: test
keys: secret
operationalEnvironment: dev
isProduction: false
cloudServiceProvider: azure # Enum: azure | gcp | aws | n/a
platformLocation: "us central"
platformIdentifier:
cloudId: "01234567"
subscriptionId: "9876abc543def"
notFunded: false
access: # Access levels with users/groups
admin:
users: ["di:3237448b-5555-4326-5555-bae3091"]
groups: ["ldap:CN=UHGRG_..._ADMIN,CN=Users,DC=ms,DC=ds,DC=uhc,DC=com"]
contributor:
groups: ["ldap:CN=UHGRG_..._CONTRIBUTOR,CN=Users,DC=ms,DC=ds,DC=uhc,DC=com"]
readonly:
groups: ["ldap:CN=UHGRG_..._READ,CN=Users,DC=ms,DC=ds,DC=uhc,DC=com"]
---
# Update an existing Resource Group (name is present)
name: <existing-rg-name>
type: APP
askId: <ask-id>
description: <updated-description>
Resource Group Read-Only Fields (do NOT set on apply)
application,businessUnit,operatingUnit,location,departmentId,glCode(IND only)uuid,offset,resourceId,pending
📐 Resource Group Access Format
Applied with hcpctl apply rg access -f:
name: <rg-name>
add:
access:
<access-level>:
users: [user1, user2]
remove:
access:
<access-level>:
users: [user3]
📐 Runtime Action Request Format
From the OpenAPI spec (RuntimeActionRequestDto). Required field: actionName.
hcpctl action <actionName> '<parameters-json>' <resourceId>
The API expects:
{
"actionName": "restart",
"parameters": {
"key": "value"
}
}
actionNamepattern:^[a-z]*([.-][a-z]+)*$parametersis optional, key-value string pairs
🌐 PRM API Endpoints (v5.2.4)
Full reference from the OpenAPI spec at https://prm.optum.com/resource-api/v3/api-docs:
Resource Operations
| Method | Path | Description |
|---|---|---|
| GET | /v1/resources | List resources (with filters) |
| POST | /v1/resources | Create a resource |
| PUT | /v1/resources | Upsert (create or update) a resource |
| GET | /v1/resources/count | Count resources |
| GET | /v1/resources/{ns}/{kind}/{name} | Get a specific resource |
| DELETE | /v1/resources/{ns}/{kind}/{name} | Delete a resource |
| PUT | /v1/resources/{ns}/{kind}/{name}/spec | Replace spec |
| PATCH | /v1/resources/{ns}/{kind}/{name}/spec | Patch spec |
| PUT | /v1/resources/{ns}/{kind}/{name}/status | Replace status |
| PATCH | /v1/resources/{ns}/{kind}/{name}/status | Patch status |
| PUT | /v1/resources/{ns}/{kind}/{name}/labels | Replace labels |
| PATCH | /v1/resources/{ns}/{kind}/{name}/labels | Patch labels |
| PUT | /v1/resources/{ns}/{kind}/{name}/annotations | Replace annotations |
| PATCH | /v1/resources/{ns}/{kind}/{name}/annotations | Patch annotations |
| PATCH | /v1/resources/{ns}/{kind}/{name}/metadata | Patch metadata |
| PUT | /v1/resources/{ns}/{kind}/{name}/platformIdentifier | Replace platform ID |
| PATCH | /v1/resources/{ns}/{kind}/{name}/platformIdentifier | Patch platform ID |
| GET | /v1/resources/{ns}/{kind}/{name}/history | Get resource history |
| GET | /v1/resources/{ns}/{kind}/{name}/readyState | Get ready state |
| GET | /v1/resources/{ns}/{kind}/{name}/children | Get children |
| POST | /v1/resources/{ns}/{kind}/{name}/children | Create child resource |
| GET | /v1/resources/{ns}/{kind}/{name}/chargeback | Get chargeback info |
| PUT | /v1/resources/{ns}/{kind}/{name}/migrations/{dest} | Migrate resource |
| GET | /v1/resources/{ns}/{kind}/{name}/actions/runtime | List runtime actions |
| POST | /v1/resources/{ns}/{kind}/{name}/actions/runtime | Trigger runtime action |
| POST | /v1/resources/validation | Validate a resource |
Resource Group Operations
| Method | Path | Description |
|---|---|---|
| GET | /v1/resource-groups | List resource groups |
| POST | /v1/resource-groups | Create resource group |
| GET | /v1/resource-groups/{name} | Get resource group |
| PUT | /v1/resource-groups/{name} | Update resource group |
| DELETE | /v1/resource-groups/{name} | Delete resource group |
| GET | /v1/resource-groups/{name}/resources | List resources in RG |
| GET | /v1/resource-groups/{name}/access | Get RG access |
| POST | /v1/resource-groups/{name}/access-modifiers | Modify RG access |
Kind Operations
| Method | Path | Description |
|---|---|---|
| GET | /v1/kinds | List all kinds |
| GET | /v1/kinds/{name} | Get kind details |
| POST | /v1/kinds/{kind}/validate/spec | Validate spec against kind |
Common Endpoints (no auth)
| Method | Path | Description |
|---|---|---|
| GET | /health | Health check |
| GET | /healthz | Health check (k8s) |
| GET | /version | API version |
🔑 Key Source Repositories
| Repository | Purpose | Key Files |
|---|---|---|
optum-eeps/prm-hcpctl | CLI tool source | cli/commands/apply.go, cli/internal/resource.go |
optum-eeps/prm-go-client-library | Client library & types | prm/resource.go, prm/types/resource.go |
https://prm.optum.com/resource-api/v3/api-docs | Live OpenAPI spec | Full API contract with schemas |
💡 Tips for Generating Apply Files
- Fetch the OpenAPI spec first to verify the current schema version and field patterns
- Use
hcpctl cat -o yaml <existing-resource>to see the full structure of an existing resource as a template - Remove system-managed fields (
status,children,id,created,updated,uuid,version,offset,event,createdBy,lastUpdatedBy,deleted,deletedBy) before using as an apply template - Always validate with
hcpctl apply -f <file> --dry-runbefore applying - The
specsection is entirely kind-specific — usehcpctl kindsto discover available kinds - Use
POST /v1/kinds/{kind}/validate/specto validate spec against kind schema without creating a resource
🔎 Discovering PRM Resource Kinds
⚠️ Always Use the Live Command
The kinds registered in PRM change over time as teams onboard new resource types. Always run hcpctl kinds to get the current list — the examples below are a snapshot and may be outdated.
🛠️ How to Discover Available Kinds
Step 1: Login and list all kinds
hcpctl context use prm-prod
hcpctl login
hcpctl kinds
This returns all registered resource kinds with their descriptions.
Step 2: Inspect a specific kind's spec schema
hcpctl cat -o yaml system/kind/<kind-name>
This is the key step. Every kind definition contains a spec.schema field that is a full JSON Schema defining exactly what fields the spec section requires. The schema includes:
required— mandatory fieldsproperties— all available fields with types, patterns, enums, min/max constraintsexamples— sample values for each fielddescription— what each field doesadditionalProperties: false— no extra fields allowed (strict validation)
The kind definition also contains:
spec.actions— runtime actions available for resources of this kindspec.description— what the kind is forspec.migrationAllowed— whether resources can be moved between namespaces
Example: artifactory.project.v1 schema
hcpctl cat -o yaml system/kind/artifactory.project.v1
Returns (spec section only):
spec:
schema:
type: object
required:
- projectKey
- technology
properties:
projectKey:
type: string
pattern: ^[a-z][a-z0-9]*(-[a-z0-9]+)*$
maxLength: 32
minLength: 2
description: Required project key which is the prefix for local Artifactory repositories
technology:
type: array
items:
enum:
- docker
- gem
- generic
- go
- helm
- helmoci
- huggingface
- maven
- npm
- nuget
- pypi
- tf-provider
type: string
description: Required list of technology types utilized by application
serviceAccount:
type: string
description: Optional, non-user MS Secure account supporting Jenkins
githubRepositories:
type: array
items:
type: string
description: Optional, list of application GitHub repositories for OIDC configuration
remoteRepositories:
type: array
items:
type: string
description: Optional, list of remote repositories needed as dependencies
artifactDeletionAllowed:
type: boolean
nullable: true
description: If true, team can delete their artifacts from Artifactory
additionalProperties: false
description: Artifactory Project, which is 1:1 with HCP Account and ASK ID
migrationAllowed: true
So a valid apply file for this kind would be:
kind: artifactory.project.v1
metadata:
name: my-artifactory-project
namespace: my-namespace
spec:
projectKey: my-team-app
technology:
- npm
- docker
githubRepositories:
- optum-tech-compute/my-repo
Example: sonarqube.project.v1 schema
hcpctl cat -o yaml system/kind/sonarqube.project.v1
Key fields from the schema:
spec:
schema:
type: object
required:
- projectKey
- projectName
- githubRepositoryPath
properties:
projectKey:
type: string
pattern: ^[a-zA-Z][a-zA-Z0-9.:\-_]*([a-zA-Z0-9]+)*$
maxLength: 255
minLength: 5
description: Required project key for which uniqueness will be enforced
projectName:
type: string
maxLength: 500
minLength: 3
description: Required friendly name given to the project
githubRepositoryPath:
type: string
maxLength: 1000
minLength: 5
description: Required GitHub repository containing source code to scan
mainBranchName:
type: string
default: main
description: Main branch name (default is "main")
qualityGate:
type: object
properties:
gateName:
type: string
description: Name of the quality gate to assign
# ... additional optional fields for analysis scope, webhooks, links, etc.
additionalProperties: false
actions:
- name: pull-settings
description: Retrieve all SonarQube settings
- name: regenerate-token
description: Regenerate SonarQube project token
- name: rg-migration
description: Change namespace and associated AD groups
- name: list-branches
description: List all branches of project
- name: list-pull-requests
description: List all pull requests of project
- name: update-quality-gate
description: Update the quality gate assigned to the project
So a valid apply file for SonarQube would be:
kind: sonarqube.project.v1
metadata:
name: my-sonarqube-project
namespace: my-namespace
spec:
projectKey: myteam-microservice
projectName: My Team Microservice
githubRepositoryPath: optum-tech-compute/my-repo
mainBranchName: main
Example: cloud-account.v2 schema (partial)
hcpctl cat -o yaml system/kind/cloud-account.v2
Key fields from the schema:
spec:
schema:
type: object
properties:
csp:
enum: [AWS, AZU, GCP]
description: The cloud service provider
org:
enum: [OPTUM, UHG, ENTERPRISE, ...]
description: The organization the account falls under
tags:
type: object
maxProperties: 13
description: Tags to be applied to the account
ask_id:
type: string
description: The group that will be billed for the account
intake:
type: object
properties:
regions:
type: array
items:
enum: [centralus, us-east-1, us-central1, ...]
intake_cicd:
type: string
description: URL to CI/CD pipeline (production accounts)
regulations:
type: array
description: Regulations that apply to the account
Step 3: Find existing resources of a kind (as templates)
hcpctl ls <kind-name>
hcpctl cat -o yaml <resourceId>
Use an existing resource as a template — copy the output, remove system-managed fields, and modify the spec for your needs.
Step 4: Validate before applying
hcpctl apply -f my-resource.yaml --dry-run
📋 Known Resource Kinds (Snapshot)
The following kinds were discovered from PRM prod. This list is a point-in-time reference — always run hcpctl kinds for the authoritative current list.
Cloud Accounts & Subscriptions
| Kind | Description |
|---|---|
cloud-account.v1 | Cloud account |
cloud-account.v2 | Cloud account (v2) |
dce.v1 | Disposable Cloud Environment (temporary sandbox) |
dce.contributor.v1 | DCE contributor access |
dojo360.cloud-account.v1 | Dojo360 cloud account |
azurestack.sub.v1 | Azure subscription |
azure-rg-v1 | Azure resource group |
JFrog Artifactory
| Kind | Description |
|---|---|
artifactory.project.v1 | Artifactory project |
artifactory.dependency-repository.v1 | Dependency repository |
artifactory.restricted-repository-access.v1 | Restricted repository access |
artifactory.shared-restricted-repository.v1 | Shared restricted repository |
SonarQube
| Kind | Description |
|---|---|
sonarqube.project.v1 | SonarQube project |
GitHub Enterprise Cloud
| Kind | Description |
|---|---|
ghec.org.v1 | GitHub Enterprise Cloud organization |
ghec.repo.v1 | GitHub Enterprise Cloud repository |
ghec.repo.v2 | GitHub Enterprise Cloud repository (v2) |
Networking & Ingress
| Kind | Description |
|---|---|
cas.ingress.v1 | CAS ingress |
cas.ingress.load-balancer.v1 | Load balancer |
cas.ingress.waf.v1 | Web application firewall |
cas.ingress.certificate.v1 | TLS certificate |
cas.ingress.dns.v1 | DNS for ingress |
cas.managed-network.aws.v1 | AWS managed network |
cas.managed-network.azu.v1 | Azure managed network |
cas.managed-network.gcp.v1 | GCP managed network |
cas.network.azu.vnet.v1 | Azure VNet |
cas.network.azu.vnet.subnet.v1 | Azure subnet |
cas.network.azu.nsg.v1 | Azure NSG |
cas.network-firewall.v1 | Network firewall |
dns.record.v1 | DNS records |
loadbalancer.vip.v1 | Load balancer VIP |
net.vpc.v1 | VPC |
net.subnet.v1 | Subnet |
Kubernetes & Containers
| Kind | Description |
|---|---|
naas-v1 | Namespace-as-a-Service |
hcp-kubernetes-cluster-v1 | HCP Kubernetes cluster |
cloudk8s-cluster-v1 | Cloud Kubernetes cluster |
kubernetes-namespace-v1 | Kubernetes namespace |
kubernetes-secret-v1 | Kubernetes secret |
k8s-namespace-credentials-v1 | K8s namespace credentials |
Databases
| Kind | Description |
|---|---|
db-pgsql.v1 | PostgreSQL database |
db-mysql.v1 | MySQL database |
db-mssql.v1 | MSSQL database |
gcp-cloudsql.v1 | GCP Cloud SQL |
pgsql-azure.v1 | Azure PostgreSQL |
mysql-azure.v1 | Azure MySQL |
aws-db.v1 | AWS database |
cosmosdb-database-v1 | CosmosDB database |
cosmosdb-cassandra-keyspace-v1 | CosmosDB Cassandra keyspace |
Kafka & Event Streaming
| Kind | Description |
|---|---|
kafka-cluster-v1 | Kafka cluster |
azure-kafka-cluster-v1 | Azure Kafka cluster |
hcc-dataplatform-kafka-topic-v1 | HCC Kafka topic |
hcc-dataplatform-kafka-acl-v1 | HCC Kafka ACL |
hcc-dataplatform-kafka-consumer-group-v1 | Kafka consumer group |
hcc-dataplatform-certificate-v1 | HCC data platform certificate |
topic-v1 | Kafka topic |
topic-acl-v1 | Topic ACL |
Elasticsearch & Observability
| Kind | Description |
|---|---|
elasticsearch-platform-saas-deployment-v1 | Elastic Cloud SaaS deployment |
elasticsearch-platform-saas-ipfilter-v1 | Elastic IP filter |
elasticsearch-platform-saas-oidcgroups-v1 | Elastic OIDC groups |
elasticsearch-platform-saas-privateconnection-v1 | Elastic private connectivity |
elasticsearch-platform-eck-deployment-v1 | ECK deployment |
ece.cluster.v1 | ECE cluster |
prometheus-v1 | Prometheus |
hcp.observabilitytenant.v2 | Observability tenant |
Snowflake & Data Platform
| Kind | Description |
|---|---|
sdrp.common.database.v1 | Snowflake database |
sdrp.common.warehouse.v1 | Snowflake warehouse |
sdrp.common.schema.v1 | Snowflake schema |
sdrp.common.tenant.v1 | Snowflake tenant |
sdrp.common.datashare.v1 | Snowflake data share |
sdrp.common.functional-role.v1 | Snowflake functional role |
snowflake-access.v1 | Snowflake access |
Databricks (UDLP)
| Kind | Description |
|---|---|
udlp.dbw.v1 | Databricks workspace |
udlp.dbw-cluster.v1 | Databricks cluster |
udlp.dbw-sqlwh.v1 | Databricks SQL warehouse |
udlp.dbw-credential.v1 | Databricks credential |
udlp.dbw-pe.v1 | Databricks private endpoint |
udlp.dbw-spn.v1 | Databricks service principal |
Compute & VMs
| Kind | Description |
|---|---|
compute-vm-linux.v2 | Linux VM |
compute-vm-windows.v1 | Windows VM |
azure-vm.v1 | Azure VM |
azure-vm-deployment.v1 | Azure VM deployment |
API Management & Gateway
| Kind | Description |
|---|---|
stargate.api.v1 | Stargate API |
hcp.stargate.api.v1 | HCP Stargate API |
federated-azure-apim.api.v1 | Azure API Management API |
federated-azure-apim.api.gql.v1 | Azure APIM GraphQL API |
api-manager-v1 | API manager |
Security & Identity
| Kind | Description |
|---|---|
secret.v2 | Secret |
secret.engine.aws.v2 | AWS secrets engine |
secret.engine.azure.v2 | Azure secrets engine |
secret.engine.gcp.v2 | GCP secrets engine |
secret.engine.kubernetes.v2 | Kubernetes secrets engine |
certificate-v2 | Certificate |
digitalidentity.client.v1 | Digital identity client |
sso-azure.v1 | Azure SSO |
sso-ping.v1 | Ping SSO |
hcp.auth.organization.v1 | HCP auth organization |
CI/CD & DevOps
| Kind | Description |
|---|---|
jenkins-v1 | Jenkins instance |
tfe.workspace.v1 | Terraform Enterprise workspace |
epp.project.v1 | EPP project |
azuredevops.project.v1 | Azure DevOps project |
HCP Platform Services
| Kind | Description |
|---|---|
hcp.event.v1 | HCP event |
hcp.event.subscription.v1 | HCP event subscription |
hcp.event.streaming.channel.v2 | HCP event streaming channel |
hcp.workspace.v1 | HCP workspace |
hcp.product-definition.v2 | HCP product definition |
hcp.form.v2 | HCP form |
hcp.graph.client.v1 | HCP graph client |
Power BI
| Kind | Description |
|---|---|
powerbi-workspace-v1 | Power BI workspace |
powerbi-workspace-access-v1 | Power BI workspace access |
PRM System Kinds (RBAC/Infrastructure)
| Kind | Description |
|---|---|
namespace | Organizational hierarchy |
kind | Resource type definitions |
group | User/service account groups |
role | RBAC permission rules |
policy | Role-to-group assignments |
service-account | Machine identities |
agent | Agent registrations |
quota | Resource limits |
secret | Encrypted secrets |
prm.namespace-apps.v1 | Application namespace |
prm.namespace-users.v1 | User namespace |
prm.rg-access.v1 | Resource group access |
prm.rg-app.v1 | Application resource group |
prm.rg-standard.v1 | Standard resource group |
🧠 Understanding the Architecture
PRM is a generic resource lifecycle manager — like a Kubernetes control plane for enterprise infrastructure:
- Kinds are registered in PRM by product teams (stored in
system/kind/) - Agents watch for lifecycle events (
Create,Update,Destroy) on their registered kinds - When you
hcpctl applya resource, PRM sets it toPendingCreateand the responsible agent provisions it - The agent reports back success/failure, and PRM transitions the resource to
ReadyorFailure
This means:
- The
specfor each kind is defined by the team that owns the agent - You can discover the expected spec by examining existing resources of that kind
- PRM handles RBAC, lifecycle, history, and chargeback — agents handle provisioning
💡 Workflow: Provisioning a New Resource
# 1. Discover what kinds are available
hcpctl kinds
# 2. Inspect the kind definition
hcpctl cat -o yaml system/kind/sonarqube.project.v1
# 3. Find an existing resource as a template
hcpctl ls sonarqube.project.v1
hcpctl cat -o yaml <namespace>/sonarqube.project.v1/<name>
# 4. Create your resource file (based on the template)
cat > my-sonarqube-project.yaml << 'EOF'
kind: sonarqube.project.v1
metadata:
name: my-project
namespace: my-namespace
spec:
# Fields discovered from step 2/3
projectKey: my-project-key
# ... other spec fields
EOF
# 5. Validate (dry run)
hcpctl apply -f my-sonarqube-project.yaml --dry-run
# 6. Apply
hcpctl apply -f my-sonarqube-project.yaml
# 7. Monitor status
hcpctl cat my-namespace/sonarqube.project.v1/my-project

