Settings
Manage security keys, authentication, and integrations.
Account
- Username
- Login method
- MFA status
- Enabled Not enabled — register a key below to activate MFA
Security Keys
Key registered! Give it a name so you can recognise it later.
-
Added · Last used
MCP Server
Connect any MCP-compatible AI client (Claude Desktop, Claude Code, Cursor…) to this dashboard.
The server is mounted at /mcp and uses a Personal Access Token for auth.
- Create a Personal Access Token in Settings → Security Keys → API Tokens (or
/tokens). - Copy the token — it starts with
vmcli_. - Add the following block to your MCP client config and replace the placeholder:
{
"mcpServers": {
"vm-dashboard": {
"url": "",
"headers": {
"Authorization": "Bearer vmcli_<your-pat-here>"
}
}
}
}
Available tools: dashboard_summary, list_jobs, get_job,
list_vms, list_ec2_instances, list_amis, list_azure_vms.
All tools are read-only — deploy/start/stop actions must be performed through the web UI.
Integrations
Enable and configure optional integrations. Changes take effect immediately.
Configure asset storage on /storage before enabling.
Reference
Documentation and API tooling shipped with this build — no internet access required for the docs.
Preview features
Early-access features with no extra configuration. Toggle on to reveal them in the nav — changes take effect immediately.
No preview features available.
Month-to-date cloud spend (AWS Cost Explorer + Azure Cost Management) shown on the
dashboard tile and the /costs page. Set a monthly budget to get an alert
when spend exceeds it — or is on pace to by month-end.
In your account currency. The dashboard's “Needs attention” panel flags
over (spend ≥ budget) and approaching (projected to
exceed by month-end). Needs ce:GetCostAndUsage (AWS) /
Cost Management reader (Azure).
Per-cloud budgets (optional)
Each cloud's MTD spend is flagged against its own budget, in addition to the overall budget above. 0 = no per-cloud alert.
GCP has no cost API — enable Cloud Billing export to BigQuery, then paste the export table here. Grant the dashboard service account BigQuery Data Viewer + Job User on that dataset. Blank → GCP cost stays unavailable. (Export data can lag ~24h; queries scan billed data, so results are cached for hours.)
Evaluate every deploy against OPA policies before the job starts. A blocked deploy returns 403 with the reason and is recorded in the tamper-evident audit log — nothing is created. See the guardrails guide.
Comma-separated. Only these actions are gated; everything else is unaffected. Leave blank and the gate is inert even while enabled.
Allow-list of regions/locations/zones. Blank = no region restriction. Edit directly or use the picker above.
Block-list of sizes/classes (EC2 type, Azure vm_size, GCE machine type, DB class/sku, node type).
Weekdays (UTC) on which deploys are frozen (mon…sun). Blank = no freeze.
Custom rules: drop a .rego into terraform/policy/admission/.
Requires the bundled OPA binary (in the image). With the gate on but OPA missing, gated deploys fail closed (403) rather than slipping through.
Give every new deployment an expiry, then permanently delete it when that time passes — the same destroy path the Destroy button uses. Terminated instances, deleted databases and destroyed clusters are not recoverable. Resources you registered rather than provisioned are never touched, and neither is anything that already existed before you enabled this: a resource only has a timer once something stamps one. See the auto-delete timer doc.
Hours. Applied to cloud VMs, databases and Kubernetes clusters the dashboard
provisions. 0 means new deploys get no timer and nothing is ever
deleted automatically — the safe way to enable this and watch it first.
The clock starts when the deploy is queued, so it includes provisioning time.
Hours, counted from when the resource was created — not from the last extension — so repeated extending can't outrun it. Admins are not capped.
Hours per click, clamped by the ceiling above.
Hours. A resource entering this window shows a warning on the dashboard, and — if is on — fires one resource.expiring message per endpoint, once each. Otherwise an operator has to open the dashboard to see it.
Min past expiry (floor 15).
Minutes (floor 5).
Cap 50.
Days, 0 = forever.
A sweep records a job every interval whether or not it found anything — 48 a day at the default. Completed ones are dropped past this age and are hidden on Job History unless you tick "Show routine sweeps"; a failed pass is always kept and always shown.
Comma-separated. Resources in these workgroups never get a timer and are never deleted. Only VMs carry a workgroup — databases, clusters and desktop seats don't, so use "never expires" for those instead. Blank = none.
Deletion runs on a schedule, not instantly, so a resource may sit briefly past its expiry. Two one-hour arming delays stand in the way and neither is configurable: the first sweep after you enable the feature only starts the clock, and turning Observe only off starts a second one — so there is always an hour, with the full list visible on Inventory, before anything is destroyed. Turning Observe only back on resets that second clock.
Long jobs — provisions, image builds, exports, deploys — run in a separate worker process, not in the web app. These limits say how many run at the same time, and are read fresh every couple of seconds, so a change here applies without restarting anything. See the job worker doc.
Image exports, promotes and copies, gateways, auto-delete sweeps. They start something in the cloud and then just wait — an export can poll for two hours. Cheap; raise this first. Max 12.
Cluster and database provisions, Packer builds. Each streams its output to the database line by line, so two is usually enough to saturate a small Postgres. Max 4.
VM deploys, tunnels, Kubernetes add-ons. Mostly cloud API calls plus a short terraform or helm. Max 4.
The overall ceiling, and the one that actually binds — the three limits above are allowed to add up to more than this, because they cap the mix while this caps the total. Lower this to shrink the worker's footprint. Max 16, but see the note below: it is also capped by how many database connections the worker has.
Seconds to let running jobs finish when the worker is asked to stop (a redeploy). Keep it under your platform's termination grace period — 30s by default on Azure Container Apps — or the process is killed before it finishes waiting. Jobs longer than this are failed promptly by the next worker instead of looking alive for ten minutes. 0 = don't wait.
0 derives it from the limits above, which is almost always
right. Set it only if the log shows jobs stuck at 0% — that means cloud
calls are queueing for a thread. Applied at worker start, so this one needs
a restart. Max 128.
Running more than one worker multiplies these limits — two workers with a total of 3 each run up to 6 jobs. Jobs are claimed atomically, so no job ever runs twice however many workers there are. Note that each worker needs its own database connections, which is why raising the limits inside one worker is usually cheaper than adding another.
Push dashboard events to Slack, Microsoft Teams, or any HTTP endpoint. Delivery is outbound only — nothing here opens an inbound webhook. See the notifications doc.
The worker has no idea what address you reach the dashboard on. Leave this blank and every message ships with no link — which looks like a bug but is this setting. No trailing path.
Comma-separated. Known: . An individual endpoint can narrow this further, but not widen it.
Below this, nothing is queued.
Seconds (floor 5).
Seconds (floor 300). Budget, stale-secret and drift checks.
Retries back off 30s → 2m → 10m → 30m and survive a worker restart. Past the queue ceiling, new messages are recorded as suppressed rather than queued — the brake that keeps a first enable against a large estate from becoming an incident.
Days. 0 = keep forever. Failed deliveries are never pruned — they're the evidence.
No endpoints yet. Nothing will be sent until you add one.
Only:
Teams: create a Power Automate Workflow from the "Post to a channel when a webhook request is received" template and paste its URL. The old outlook.office.com connector webhooks were permanently switched off in May 2026 and will not work. Messages post as the Flow bot; the name and icon can't be changed.
Slack: an Incoming Webhook URL from the Slack app that owns the channel.
Any endpoint that accepts JSON. The body is a stable, versioned envelope; set a secret below to have it signed with HMAC-SHA256.
Sent as X-Dashboard-Signature. An aws_sm:// / azure_kv:// / gcp_sm:// / bt_safe:// reference is resolved at send time.
Nothing recorded yet.
Delivery is at-least-once: a worker killed mid-send retries when the row is reclaimed, so a duplicate message is possible. A failing endpoint can never slow down or fail the job it is reporting on — sending happens in a separate process, after the fact.
BeyondTrust Password Safe / Secrets Safe — on-demand checkout of secrets and
managed-account credentials via the ps-cli
binary, plus onboarding of the VMs, cloud databases and Kubernetes ServiceAccount
tokens this dashboard builds as managed systems and accounts.
Shell Jump, Gateway and PRA Vault configuration lives on the panel.
API connection
Secret retrieval and managed-account credential checkout via the
ps-cli binary.
Required for the Password Safe Terraform provider (VM managed-system onboarding).
Resource registration (VMs)
Optionally onboard each built Linux VM into Password Safe as a managed system + its baked-in
adminuser account, via a per-deploy opt-in on the
cloud deploy forms. Each cloud defaults to its cloud-native plugin (no per-VPC Resource Broker):
AWS → AWS Systems Manager (over SSM), Azure →
Azure VM SSH Rotation (over Run Command), GCP → GCP VM SSH
Rotation (over GCE instance metadata). The functional account per cloud decides the
management method; each cloud can be switched to the traditional SSH flow below.
Manages Linux EC2 over AWS SSM SendCommand — no SSH
line-of-sight needed. The AWS functional account must be the AWS Systems Manager Custom Plugin
account (password {AccessKeyID}:{AccessKeySecret}), the
plugin must be admin-uploaded in BeyondInsight, and each instance must already be SSM-managed.
Traditional managed system keyed by hostname/IP; pushes the VM's own SSH key and needs SSH line-of-sight (Resource Broker / Gateway). GCP always uses this method (Azure has its own below).
Rotates the adminuser key over Azure VM
Run Command — no SSH line-of-sight needed. The Azure
functional account must be the Azure VM SSH Rotation Custom Plugin account (username = Azure
app/client ID, password = client secret), the plugin must be admin-uploaded in BeyondInsight, and the
service principal needs Virtual Machine Contributor on the resource group. Managed system
address = tenantId/subscriptionId/resourceGroup/vmName.
Traditional managed system keyed by hostname/IP; pushes the VM's own SSH key and needs SSH line-of-sight (Resource Broker / Gateway).
Rotates the adminuser key by writing it into the GCE
instance's ssh-keys metadata — no SSH line-of-sight
needed. The GCP functional account must be the GCP VM SSH Rotation Custom Plugin account
(username = service-account email, password = the service-account JSON key), the plugin must be
admin-uploaded in BeyondInsight, and the service account needs
roles/compute.instanceAdmin.v1. OS Login must
be disabled on the instance (metadata ssh-keys
is ignored when OS Login is on). Managed system address =
projectId/zone/instanceName.
Traditional managed system keyed by hostname/IP; pushes the VM's own SSH key and needs SSH line-of-sight (Resource Broker / Gateway).
local for IAM-user mode; an AssumeRole ARN for EC2 cross-account mode.
The functional account + workgroup must already exist in Password Safe. The per-deploy opt-in
appears as “Onboard into Password Safe” on the AWS/Azure/GCP deploy forms. For AWS Systems Manager,
the managed system DNS name is {instance-id}:{region}
and the account name is {name};{suffix}.
A PRA Vault username/password account named <cell>-adminuser
is associated to the cell's Jump Group and kept current via a Password Safe
SyncedAccounts link through the PRA Vault Username Password plugin — so the
credential is check-out-able and injectable in PRA. Blank fields fall back to the cloud-database
PRA Vault settings below.
Database Import
Tunes the Import from Password Safe button on the Databases page,
which lists the databases Password Safe already knows about and registers the ones you pick.
It only reads — nothing in Password Safe is created or changed.
All four are optional. Importing needs both the cloud_database:write
and secrets:use permissions.
Preselected in the import dialog. Password Safe does not record a cloud, so this is a starting point, not a lookup.
The dialog says so when it truncates — narrow with a workgroup rather than raising this.
Maps a Password Safe platform name to postgres, mysql, sqlserver or oracle. Invalid JSON is ignored.
Database Onboarding (AWS & Azure)
When on, provisioning an AWS or Azure database creates a dedicated managed DB user, onboards the DB as a
Password Safe managed system + managed account (via the {engine} SSM Custom Plugin
on AWS, the {engine} Azure Run Command Plugin on Azure),
and onboards the PRA Vault credential (via the PRA Vault Username Password plugin)
so Password Safe propagates rotations into the tunnel-injected credential. GCP and OCI are not supported.
The custom plugins + the RSA key prep are one-time manual setup — see the database onboarding guide.
Sets Change Password Using Own Credentials on the managed
account, so the DB plugin rotates it in place instead of calling the via-functional-account action —
which needs a privileged DB login (CREATEROLE /
CREATE USER /
ALTER ANY LOGIN) that a provisioned server does not have.
Required with an operator-created functional account — that account is unprivileged on
the database, so only the self-rotate action can change a credential. Keep the functional account names in
SP: form and the Azure credential comes from the account
itself, so an off-Azure Resource Broker needs no extra setup. Their DB password segment must still be
valid: it is unused by a self-rotate change but Verify Functional Account logs in with it.
The dashboard resolves the functional accounts you name below and never creates or deletes them — the same contract as the VM and Kubernetes onboarding. Each managed system inherits its account's platform, so the Platform fields become advisory, and the cloud credential stays in Password Safe instead of this config store. One account per engine per cloud, because a functional account belongs to a platform.
The dashboard creates a functional account per database from the credential material below, and deletes it on decommission. Switch to Reference an existing account to point at accounts you created yourself.
The functional account packs the AWS credentials for SSM SendCommand: setting both the Access Key ID and Secret selects IAM-user mode; leaving either blank selects EC2 instance-role mode (Password Safe node/broker on an EC2 with the SSM role). The account's username becomes EC2:<dbAdmin> / IAM:<dbAdmin> and its password the keyId:secret:dbAdminPassword triple the plugin parses.
Not used in this mode — the functional account you name above carries it.
Plugin RSA key material the dashboard drops onto the shared SSM jump host so the SSM plugin can decrypt the RSA-wrapped login password. Use a separate key pair from the Azure one below: these two private keys land on different hosts, so sharing one would mean a compromise of either host also decrypts the other cloud's payloads. Blank leaves the staging manual.
The PRA Vault plugin authenticates with the PRA Configuration API account on the panel. Unsaved edits here are discarded when the panel switches.
Azure (Run Command plugins)
For Azure databases the DB is onboarded onto the {engine} Azure Run Command Plugin,
whose plugin reaches the private DB by running the DB client on the shared clouddb-jumpoint VM
via Azure VM Run Command. The functional account is the minted DB admin bundled with an Azure service principal; it rotates a dedicated
managed user. The three custom plugins + the RSA keypair (public cert on the Resource Broker, private key below) are one-time manual setup.
Azure databases skip Password Safe onboarding and fall back to the legacy admin-credential staging; the AWS SSM path above stays on. The checkbox above is shared by both clouds, so this is the only way to disable Azure alone.
Azure service principal for the functional account — leave blank to reuse the dashboard's Azure credentials. It needs Virtual Machine Contributor on the jump-VM resource group.
Not used in this mode — the functional account you name above carries it.
Plugin RSA private key + passphrase the dashboard drops onto the jump VM at /root/psplugin (matches the public cert on the Resource Broker).
GCP (Cloud SQL plugins)
For GCP databases the DB is onboarded onto the GCP Cloud SQL {engine} plugin.
PostgreSQL and MySQL use the Data API channel, which reaches a private-IP instance through
Google's own control plane — so unlike AWS and Azure there is no jump host, no broker certificate and no RSA key
pair, and under IAM database authentication the functional account has no database password at all.
SQL Server uses the Cloud Run channel, because Cloud SQL for SQL Server has no IAM database
authentication; that channel needs a small Cloud Run service you deploy yourself, and the dashboard only needs its audience below.
Channel readiness is uneven. Cloud Run is built (SQL Server only) but has not yet been exercised against a live Cloud SQL instance. The Data API channel is still a stub — a PostgreSQL or MySQL rotation reports “not implemented in this build” rather than succeeding.
GCP databases skip Password Safe onboarding and fall back to the legacy admin-credential staging; the AWS and Azure paths above are unaffected.
Automatic follows the plugin's own recommendation per engine. Cloud Run is also the only channel that can verify a managed account's password or let one rotate itself.
Operator-created functional accounts, one per engine. This is the recommended mode on GCP: unlike Azure the composite carries nothing per-database, so a single account covers every Cloud SQL instance on that platform.
An attached service account on a Compute Engine Resource Broker, or GOOGLE_APPLICATION_CREDENTIALS
on an on-premises one. No key material is stored in Password Safe or here.
A base64 service-account key is roughly 3.2 KB, over Password Safe's 1000-character credential limit — so the composite cannot survive a functional-account write-back. Prefer ADC or IMP.
The broker's identity needs roles/iam.serviceAccountTokenCreator on this account.
Operator-created, and used by the Data API channel only. The dashboard registers it as an IAM database user on
each instance it onboards and reads back the name the database actually stored. Keep the name short —
MySQL truncates an IAM database username at the @ and caps it at 32 characters.
Cloud Run channel (SQL Server)
The Cloud Run service holds the database drivers and connects over direct VPC egress. You deploy it — the
plugin repository ships a ps-dbops-sqlserver Terraform module, and the dashboard
cannot build its container image. Grant each Resource Broker's identity
roles/run.invoker on it, named service accounts only.
The service's stable custom audience, not a revision URL — it is sent verbatim as both the request target and the token audience, so the string configured on the service is the string that goes here. A path, query or fragment is rejected. Blank leaves SQL Server onboarding off, because there would be no address to build.
Kubernetes Token Rotation
Makes a cluster's PRA-injected ServiceAccount token a Password Safe managed account on the
Kubernetes Service Account Token plugin so it rotates on schedule,
and registers the PRA Vault copy as a second managed account on the
PRA Vault Token plugin. Registration then syncs the two in
Password Safe, so every rotation reaches PRA with nothing running on the dashboard's side.
Importing the two plugins, creating the functional accounts, and granting the API identity Requestor + an
auto-release access policy on the new managed accounts are one-time manual setup — see the
token rotation guide.
Neither account's access policy may enable "Change Password After
Release" — a credential change on either member of a synced pair re-rotates both, so a
release-triggered change on the PRA copy would rotate the real cluster token.
Functional accounts (name or id). Per cloud: an AWS access key, an Entra service principal (SP:<tenantId>:<clientId>), a GCP service-account key, or a bootstrap ServiceAccount credential for on-prem/OKE. The PRA Vault mirror's is a PRA Config-API OAuth client.
In-cluster rotator RBAC. The binding subject differs per cloud: AKS needs the service principal's object id (the plugin logs it on every run — not the client id), EKS the access-entry username + the IAM principal ARN behind the functional account's key. GKE derives the subject from the functional account's name when blank.
There is nothing to tune for PS → PRA delivery: registration syncs the PRA Vault account to the token account in Password Safe, and a managed account and its subscribers always share a credential, so rotations reach PRA as part of the change itself. In LongLived mode the old token is revoked at rotation, so use Bound mode on clusters whose tunnel must not break — Bound never revokes, and the old token stays valid until its TTL.
The managed account name is <namespace>/<serviceaccount>,
taken from the Kubernetes tunnel identity on the
panel. Unsaved edits here are discarded when the panel switches.
BeyondTrust Privileged Remote Access brokers access to everything the dashboard builds — Shell Jump, Web Jump, Remote RDP and Protocol Tunnel jump items, plus PRA Vault accounts. Provisioned via the BeyondTrust SRA Terraform provider (ARM64-native, no binary dependency).
The Jump Group and Gateway named below must already exist in PRA — the dashboard looks them up by name, it does not create them. Gateway hosts are deployed from the Containers page.
API connection
Shell Jump provisioning via the BeyondTrust SRA Terraform provider. Runs natively on ARM64 — no binary dependency.
Configuration API account
For the few calls the SRA Terraform provider cannot make — the PRA Vault accounts used by cloud-database onboarding. Optional: leave blank to reuse the credentials above.
Shell Jump provisioning
The Jump Group and Gateway must already exist in PRA — the dashboard looks them up by name and creates Shell Jumps inside them.
Size of the shared ECS Gateway host. A Web Jump renders headless Chromium on the Gateway and needs ≥2 GB — t3.small minimum, t3.medium preferred. Changing this never resizes a live host: terminate the Gateway host instance and the next deploy recreates it at the new size. Blank keeps the default (t3.small).
Azure overrides — leave blank to reuse the AWS values above.
Applies to single deploys; a batch always shares one ACI group. ACI is Shell-Jump only — it cannot do protocol tunnels — and every group mounts the same /jpt share, so they contend over one Gateway identity. A deploy that supplies its own Gateway deploy key always gets ACI, since the shared host uses the configured key.
Size of the shared Gateway VM. A Web Jump renders headless Chromium on the Gateway and needs ≥2 GB — Standard_B1ms minimum, Standard_B2s preferred. Changing this never resizes a live Gateway: delete the Gateway VM and the next deploy recreates it at the new size. Blank keeps the default (Standard_B2s).
EC2 has no per-instance external-IP switch — the subnet's MapPublicIpOnLaunch decides — so a cell deployed into a public subnet comes up addressable from the internet and the air-gapped "plant network" the demo rests on is gone. Checked, the deploy refuses before launching anything. GCP and Azure cells pin the external IP off in the form and are unaffected.
Adds three firewall rules per cell, on its ot-sim network tag: no route out at all, and inbound only from the PRA Gateway's bt-jumpoint tag. They outrank the on-demand egress rule, so a cell stays air-gapped even with gcp_vm_nat_enabled on — without them, turning on egress for one ordinary VM quietly gives every plant cell a route to the internet. Removed with the cell; existing cells pick them up on Re-wire. AWS and Azure cells are unaffected.
GCP overrides — leave blank to reuse the AWS values above.
Applies to single deploys; a batch always shares one Gateway. Paired costs an extra e2-micro per VM. A deploy that supplies its own Gateway deploy key is always paired, since the shared host uses the configured key.
Size of the shared Gateway host. A Web Jump renders headless Chromium on the Gateway and needs ≥2 GB — e2-small minimum, e2-medium preferred; below that the session is OOM-killed and the failure looks identical to a blocked firewall. Changing this never resizes a live Gateway: delete the Gateway VM and the next deploy recreates it at the new size. Blank keeps the default (e2-medium).
Kubernetes tunnel identity
The ServiceAccount PRA injects into a managed cluster for API-server tunnels, and the PRA Vault account group injected Kubernetes, database and Web Jump credentials land in. Password Safe can rotate this token on a schedule — see the panel.
Site ID + Personal Access Token for the BeyondTrust Endpoint Privilege Management
for Linux API, on the Pathfinder gateway at
api.beyondtrust.io. Used to build and
download EPM-L client packages, sync them to asset storage, and mint activation tokens.
Find your Site ID by opening
app.beyondtrust.io/api/platform/currentSite
while signed in and copying the site_id
field. The PAT must be created while that site is the active one — PATs are bound to
the site, not the user.
Containers are shown for every configured cloud provider (AWS ECS, Azure ACI, GCP Cloud Run) automatically. To also manage on-prem Docker hosts, either deploy a managed Portainer CE server from Containers → Portainer (which fills in the URL and token below for you), or connect one you already run.
Personal Access Token from Portainer (My account → Access tokens), or a vault
reference like bt_safe://Portainer_PAT,
aws_sm://…,
azure_kv://…,
gcp_sm://…. Stored encrypted.
A dashboard-deployed node serves a self-signed certificate, so deploying one turns this off automatically.
Managed Portainer server
Settings for a Portainer CE container the dashboard runs on a GCE Container-Optimized-OS VM. The node is ephemeral — a teardown wipes its users, environments and settings.
Comma-separated. Opens tcp 9443 (UI/API) and
8000 (Edge agent) to these sources only.
Empty is fail-closed unless "Allow open" below is on — the dashboard's own
egress IP is added automatically so a deploy can reach its node.
The dashboard's own public egress range. Auto-detected and saved on each deploy; set it by hand if you egress from a proxy pool (detection won't clobber a broader range that already contains the detected IP).
First-run password for the admin user.
Leave blank to auto-generate one (it is shown once on the Containers page).
Stored encrypted.
0.0.0.0/0) when no CIDRs are set
— GCP
0.0.0.0/0) when no CIDRs are set
— AWS
0.0.0.0/0) when no CIDRs are set
— AZURE
Users, environments and settings survive a teardown and come back on the next deploy. On GCP and AWS the disk is zonal, so it pins the node's zone — moving region needs a snapshot, not a redeploy. It keeps billing on every cloud until you tear the node down with Delete the data disk ticked.
Opt-in. Reach the node from the PRA representative console — brokered and recorded — without adding your IP to the CIDR list. The Gateway's egress IP is auto-allowed, and with a Vault account group the admin password is injected instead of shown. Can also be chosen per-deploy on the Containers page.
Effective firewall sources (closed — node unreachable)
Dashboard egress:
Web-Jump Gateways:
Merged allow-list:
none
Ports:
Remote Worker runs three kinds of job — config-management (Ansible), Kubernetes (kubectl/helm), and image-promote — either in-process or as a one-shot cloud task (AWS ECS Fargate, Azure ACI, GCP Cloud Run) with clean egress, chosen per the job's target cloud. All three share the per-cloud network settings below. Configure one storage backend for Ansible playbooks (S3 / Azure Blob / GCS).
Runner backends
Pick where each job runs by its target cloud: in-process on the dashboard host (Local), or as a one-shot task in that cloud — clean egress, for when a TLS-inspecting corporate proxy blocks direct access. Image-promote always runs in its target cloud, so it needs no selector here.
Ansible (config-mgmt) runner
Runs playbooks on your VMs over SSH, chosen by the run's target cloud.
Kubernetes (kubectl/helm) runner
Runs cluster-API ops (Entitle agent, ESO, mgmt-plane) chosen by the cluster's cloud.
Image-promote runner
A one-shot container (ECS / ACI / Cloud Run / Container Instances) that converts & stages a promoted disk image in the target cloud. It reads the hub artefact over a short-lived presigned URL, then writes to that cloud's staging bucket.
Blank → the public Docker Hub image; set a full registry path to use a private mirror (e.g. your ACR). Used for all four target clouds.
AWS — ECS Fargate
The task role is required and has no fallback — the Ansible runner's role can't write the S3 staging object. The rest falls back to the ECS Ansible-runner plumbing (cluster, subnet, SGs, execution role) and your S3 storage backend.
Must hold the source disk plus ~2 GiB for the offline image edit. Fargate's implicit default is 20 GiB.
Azure — Container Instances
The runner writes the staged VHD with the dashboard's own Azure service principal, so no extra IAM plumbing is needed — only the resource group and staging account matter, and both fall back to your Azure configuration.
GCP — Cloud Run Jobs
The project comes from gcp_project_id. The runner needs roles/storage.objectAdmin on the staging bucket — either via the service account below or the dashboard's own SA.
Cloud Run's /tmp is memory-backed and the GCP path materialises the VHD, a full raw disk, and the tar.gz there, so the default is 4 CPU / 16Gi — multi-GB images OOM at 4Gi. Jobs take whole vCPU only (1, 2, 4, 6, 8), and memory is capped by the CPU count, so raise both together: 2 CPU tops out at 8Gi, 4 at 16Gi, 6 at 24Gi, 8 at 32Gi.
OCI — Container Instances
OCI's only remote-worker task is the image-promote runner. The staging bucket is required; the rest fall back to your OCI configuration.
Shared cloud infrastructure
Used by the Ansible runner, the Kubernetes runner, and the image-promote runner. Only the cloud(s) selected above are shown.
Carries kubernetes.core + community.postgresql/mysql/general. The winrm image lacks these, so k8s/DB runs always use this image.
AWS — ECS Fargate
Azure — Container Instances
Resource group + location come from the Azure configuration.
ACR credentials (only for a private registry image; blank for Docker Hub).
GCP — Cloud Run Jobs
Ansible runner
Config-management playbooks run on your VMs over SSH.
Default SSH login per cloud's stock image.
Kubernetes runner
Asset storage — configured — required
Active backend: . Enable the Remote Worker feature flag below to start running playbooks.
The Remote Worker feature flag can't be turned on until at least one storage backend is configured and selected as active. Configure storage on the dedicated /storage page, then return here to enable Remote Worker.
Entitle integration. As the dashboard builds Linux VMs and databases it registers each as an Entitle integration (SSH ephemeral accounts / PostgreSQL / MySQL / SQL Server) so users can request just-in-time access in Entitle. Requires an Entitle tenant.
Owner ID and Workflow ID are required to register VMs & databases in Entitle.
Leave blank — each VM registers with its image's cloud-default login user automatically. Set this only to force a different sudo user for all SSH registrations.
The SSH private key is taken from the VM's own keypair (the key cloud-init injected), resolved per-cloud — not configured here.
Agent token: — auto-minted; attached to private (PRA-only) targets.
Machine identity (cloud-side JIT)
Routes cloud SDK writes (EC2 deploy / Azure VM / GCP compute) through Entitle-issued short-lived grants instead of baseline credentials. Per-cloud opt-in lets you promote one cloud at a time.
Each entry: "cloud:resource:verb" → {"bundle_id": "..."} or {"role_id": "..."}. Anything outside the matrix is denied (fail closed).
User JIT (dashboard access)
Surfaces a Request access link in the nav and deep-links from
the dashboard's 403 page to the matching Entitle resource so users can
self-serve missing permissions. Populate the resource map from the
resource_ids output of terraform/entitle_user_jit/.
Base URL of your Entitle portal's VM Dashboard bundle. The 403 page falls back to this when a missing permission has no specific resource id in the map below.
Paste the resource_ids output of
terraform/entitle_user_jit/ (Phase 2).
Keys are "scope:level"; e.g.
"aws:write".
access_token_expire_minutes
means a revoked Entitle grant takes effect on the user's next request rather than at the
token's natural expiry. The design recommends ≤30 minutes for
high-sensitivity tenants.
Connects to a Windows host running Hyper-V via WinRM (Windows Remote Management). Runs PowerShell Hyper-V cmdlets remotely — no agent required on the host. Works with Windows Server 2016–2025 and Windows 10/11 Pro / Enterprise with Hyper-V enabled.
WinRM must be enabled on the host:
Enable-PSRemoting -Force
See integration guide for full setup.
Connects to a vCenter Server or standalone ESXi host via the vSphere Web Services API.
Works with vCenter 6.7+ and ESXi 6.7+. Requires pyVmomi (installed by default).
Standalone ESXi returns ha-datacenter as the datacenter name.
vCenter exposes the full inventory — use the datacenter filter to scope the VM list.
Skytap hosts the multi-VM, multi-OS templates a customer POV runs on. The dashboard creates an environment from a template, then wires its VMs into that POV's PRA and Password Safe tenant.
Connection
Leave as the default unless your account is on another region's endpoint.
From your Skytap account page — not your account password.
Optional
Scopes new environments to a Skytap project, for access control and usage reporting.
Connects to a Proxmox VE node or cluster via the REST API. Supports API token auth (recommended) or username/password.
Connection
API Token Auth (recommended)
Password Auth (fallback)
Connects to Prism Central (or Prism Element) via the Nutanix REST API v3. Supports start, graceful ACPI shutdown (requires Nutanix Guest Tools), force stop, reboot, reset, pause, and resume.
The API user needs the Prism Admin or Cluster Admin role. See integration guide for full setup.
Containerised agents run inside a private network and poll out to this dashboard for work, so on-premises Kubernetes clusters and databases can be discovered without opening any inbound firewall rule. Register and revoke them on the Agents page.
This publishes /api/agent for agents to reach —
the only API here that serves callers outside your own network.
Terminate TLS in front of the dashboard first. Signing gives the
agent protocol integrity and replay protection, not confidentiality; see
the remote agent docs and
docker-compose.agent.yml.
The origin agents reach you on. Leave blank only if nothing sits in front of the
dashboard — behind a reverse proxy the signing audience would otherwise be derived
from the request scheme, and an audience pinned as
http:// makes every agent fail authentication in a
way that looks exactly like a revoked agent. Also fixes the OAuth callback URIs.
Signing audience — pinned, read-only
Not pinned yet. The next enrolment code pins it permanently to .
New enrolment codes are refused until this is resolved, or until you confirm the prompt to issue against the pinned value anyway.
Clears the pin so the next enrolment code re-pins it from Public base URL. Every enrolled agent stops authenticating and has to be re-enrolled with a fresh code — each one signs against the audience it was handed at enrolment.
Connects to an XCP-ng or XenServer host or pool master via the XAPI XML-RPC API (Python stdlib — no external SDK required). Supports start, graceful shutdown/reboot (requires xe-guest-utilities), force stop, hard reboot, suspend, resume, pause, and unpause.
Connect using the pool master address. Root or equivalent admin access is required. See integration guide for full setup.
Per-cloud Managed-DB network placement. Normally populated by
setup-<cloud>.sh + the sandbox --push-only import;
set or override the values by hand here. Enable or disable the feature with its
toggle in the integrations list above.
AWS RDS
Azure Flexible Server
GCP Cloud SQL
Defaults for provisioning AWS EKS (and OCI OKE) clusters. Normally
populated by setup-aws.sh + the sandbox --push-only import; set
or override the values by hand here. Registering an existing cluster from its kubeconfig
needs none of this. Enable or disable the feature with its toggle in the integrations list
above.
AWS EKS — cluster networking
EKS requires two subnets in distinct AZs. The provision form can override these per-cluster.
AWS EKS — defaults (optional)
The EKS build creates + peers its own VPC. Must not overlap the sandbox VPC (10.99.0.0/16); the provision form can override it per-cluster.
OCI OKE — defaults (optional, experimental)
The OKE build creates its own VCN (api / nodes / lb subnets carved from this block). Must not overlap the sandbox VCN (10.98.0.0/16); the provision form can override it per-cluster.
Entra group → cluster RBAC (real-identity JIT)
Default Entra (AAD) group the k8s Entra group cluster action binds — members get the role below, and Entitle's Entra-ID integration JIT-grants membership so a user signs in as themselves (no impersonation). Each cluster's action can override the group id.
e.g. cluster-admin, admin, view, or a custom ClusterRole — the action lets you pick per-bind.
Subject Entitle's Kubernetes integration binds for a JIT grant (<prefix>:<email>) — and what a user passes to kubectl --as= with the Impersonation access action.
Entra OIDC federation (EKS)
Shared Entra app registration the Entra federation action associates as an EKS cluster's OIDC identity provider, so a user's Entra token authenticates and its group Object IDs match the binding above. AKS is natively Entra-integrated (no federation needed); GKE uses Workforce Identity Federation (separate). See the federation guide.
The shared Entra app registration's Application (client) ID — the OIDC audience. Required to federate EKS.
Blank derives from the tenant id. The Entra app needs the groups claim on the ID token + public-client flows for kubectl oidc-login.
GKE Workforce Identity Federation (GKE)
GKE can't use an OIDC identity provider (GKE Identity Service is off for new orgs), so the Entra federation action wires the cluster to a Workforce Identity pool + Connect Gateway. The RBAC subject becomes principalSet://…/workforcePools/<pool>/group/<entra-oid> — the same Entra group. Create the pool + Entra OIDC provider once at the org level (gcloud iam workforce-pools); see the federation guide.
The pool's OIDC provider needs the attribute mapping google.groups=assertion.groups so the Entra group Object IDs reach the token.
Rancher management node (GCE COS)
The central Rancher server runs as a single privileged container on a public Container-Optimized-OS GCE VM (deployed from the Containers page). Every k8s cluster is imported into it — the cattle-cluster-agent dials out to the node, so private clusters on any cloud / on-prem work as long as they have egress. The node is ephemeral: a stop/recreate changes its IP and wipes state. See the integration guide for full setup.
Used once to bootstrap the Rancher admin on first boot; the API token is minted from it and stored encrypted.
GCE firewall source ranges for the node's public IP (tcp 80/443). Dashboard-provisioned clusters' egress IPs — and, when the Web Jump is enabled, the dashboard-managed Gateway's egress IP — are added automatically. Use this only for extra operator/human IPs and pre-existing (operator-owned) Gateways. If nothing is set here and nothing is auto-discovered, the firewall stays closed unless you tick "Allow open".
The dashboard reaches the node over its public IP to bootstrap it, so its own egress must be allowed. Auto-detected + saved on deploy. Corp proxies (Cloudflare WARP) egress from a pool of IPs — set the pool's CIDR (e.g. 104.28.182.0/24) and it is kept as long as the detected IP falls inside it. Bare IP → /32.
Pick runner when this network TLS-inspects and blocks the node's self-signed cert (deploy fails with "HTTPS handshake terminated in transit"). Reuses the k8s runner's GCP region + VPC connector; calls target the node's internal IP.
The Cloud Run VPC connector's /28 — auto-added to the node firewall so the runner's internal traffic is admitted.
Effective firewall allow-list
No sources yet — provision a cluster, enable the Web Jump, or add a CIDR above.
Rancher needs ≥4 GB RAM.
Rancher needs ≥4 GB RAM — t3.small (2 GB) OOMs.
Rancher needs ≥4 GB RAM — Standard_B1s (1 GB) OOMs.
How long the deploy waits for Rancher to serve after boot. Raise it for a cold image pull / slow disk.
Opt-in. Reach the node from the PRA representative console — brokered and recorded — without adding your IP to the CIDR list. The Gateway's egress IP is auto-allowed, and with a Vault account group the admin password is injected instead of shown. Jump Group, Gateway and Vault account group can also be chosen per-deploy on the Containers page — these are the defaults it starts from.
Which dashboard-managed Gateway brokers the UI. Azure's host has no public IP — add that one to the CIDRs by hand.
Defaults for Azure VDI desktop pools. Normally populated by
setup-azure.sh + the sandbox import; set or override the values by hand
here. Each pool can still override them at create time. Enable/disable the feature with
the Preview toggle.
Azure — desktop pool networking
Must be a non-delegated subnet whose NSG allows outbound 443 —
the RS jump client registers with the appliance at first boot. The sandbox creates
desktops-subnet for exactly this. Do not use aci-subnet:
ACI-delegated subnets can't host VM NICs.
Azure — defaults (optional)
Win 11 / Trusted Launch needs a Gen2 size (e.g. Standard_D2s_v3) — not a B-series.
Numeric PRA Vault account-group id — the per-seat Windows admin credential is stored there and injected at RDP launch (Phase 2). Blank → the account lands in PRA's Default group.
Per-region config sets
Run several regions in one account? Each region's resource group, subnets, DNS zone,
gallery, and default VM size now live in the
panel (alongside AWS and GCP). Blank fields fall back to the flat azure_*
keys above, so single-region setups are unchanged.
The dashboard builds a deterministic zip from
web_dashboard/functions/, uploads it to an object store
in the same cloud as the function, and Terraform references it by
content hash. Configure the store for each cloud you want to deploy to — a cloud
without one is offered but blocked in the deploy form. Enable/disable the feature
with the Preview toggle.
Integration guide.
Package stores
Every GCP deploy runs Cloud Build and pushes an image to Artifact Registry
(60–120 s). terraform destroy removes the function but leaves
those images behind.
Uses the dashboard's existing storage account (storage_azure_account);
the key is resolved over ARM at deploy time, never stored.
B1 is the cheapest SKU that supports both VNet
integration and run-from-package. Y1 (Consumption) is cheaper but
cannot do VNet integration — pairing it with a subnet fails at plan time.
VPC / VNet attachment (optional)
Only needed for functions that must reach private resources. Leave blank to deploy public-only functions.
Comma-separated. A VPC-attached Lambda has no internet access unless these subnets route through NAT.
Typically one already allowed into the database's security group.
Must be delegated to Microsoft.Web/serverFarms — a
different subnet from the database one (delegated to the DB
service). The module also sets WEBSITE_DNS_SERVER, without which
privatelink.* zones never resolve even when routing is correct.
Direct VPC egress — no connector, so nothing is billed while idle and the attachment is created and destroyed with the function. It is region-locked: give a bare subnet name (not a regional self-link) so it resolves in whatever region the function lands in. Reaching an internal IP in another region silently drops traffic.
Leave blank and the function runs as the broad default compute SA — and gets no per-secret accessor binding, so it cannot read its own bearer secret.
Only needed to reach another region from a region-pinned
function — the one thing direct egress cannot do. Ignored when the network and
subnetwork above are set. An existing connector runs a minimum of two
e2-micro instances (~$26/mo) whether or not the function is invoked.
Preview. Workload Credentials is not yet generally available, and its API may still change. Requires a US-region Pathfinder site with the feature enabled.
Mint short-lived AWS and Azure credentials on demand instead of storing static keys. This is additive: each cloud is opted in separately, and any cloud left off keeps using the credentials it uses today. GCP is absent because Workload Credentials mints AWS and Azure only — a mixed install is normal. Enable/disable the feature with the Preview toggle. Integration guide.
Connection
Your site (tenant) GUID — the tenant_id claim in the access token
your browser holds after signing in to Pathfinder.
Created under Manage Profile → Personal Access Tokens. Stored encrypted; the box is always empty — leave it blank to keep the stored token, type to replace it, or clear it to remove it. A PAT is scoped to a single site. This is the one long-lived credential this feature still needs — it replaces the per-cloud static keys rather than eliminating secrets entirely.
The version is sent as the mandatory bt-secrets-api-version header.
A wrong value fails in a way that looks like an authentication error, so change it
only when BeyondTrust says to.
Authenticates with GET /session — it proves the token, the site ID and
the API version together without issuing a credential, so it is free
and safe to repeat. Tests the saved values, so save first. Unlike
Active credential source below, this asks BeyondTrust rather than replaying the last
stored result.
Static secrets (free, unmetered)
Where the Secrets page writes when Workload Credentials is the selected backend. Static secrets are not metered — only dynamic credential issuances are.
Dynamic credentials (billed per issuance)
Each cloud below is opted in separately, and each stays off until you have created the matching dynamic secret in Workload Credentials. Turning one on reroutes that cloud's credentials on the next refresh; the other clouds are untouched. Prefer a TTL of an hour or more on the dynamic secret — issuances are metered, and AWS credentials cannot be revoked early anyway, so a short TTL buys nothing.
Set this to split the credential by lifecycle. Everything outside a job uses this
lease; the provisioning lease is minted only while a job runs and is never
pre-warmed, so iam:PassRole and iam:CreateRole
are absent from the stored credential between jobs — which is the point
of the split.
Not literally read-only, despite the setting name. The dashboard writes on the request path too — editing a secret, uploading to storage, re-tagging a VM, starting a container task. Its session policy needs those, and only needs to exclude IAM. A strictly read-only policy here breaks the Secrets and Storage pages.
It can point at the same role as the provisioning secret with a narrower session policy. Leave blank to use one lease for everything, which is the default and changes nothing.
Regenerate once less than this share of a lease's lifetime remains. Lower means fewer issuances but a smaller safety window; the value is clamped to 1–99 because 0 would pin a dead lease and 100 would bill an issuance on every check.
Active credential source
What each cloud is actually using right now. Worth checking after changing anything above — a broken lease and a cloud still on its static key look the same from the outside otherwise.
|
expires
minted when a job runs
no lease yet
static key in the encrypted config
no credential configured
|
readonly is the lease every page and API call uses.
provision carries write privilege and is minted only while a
job is running, so no lease between jobs is normal — that is the point of
the split.
Point this at any OpenID Connect provider — the authorize, token and JWKS endpoints are read from the issuer's discovery document, so there is nothing else to fill in. SSO goes live as soon as an issuer and client id are saved; clear the issuer to turn it off. Sign-in with Microsoft is configured separately under Azure and is unaffected. See integration guide for full setup.
Register this redirect URI with your provider
Base URL only — /.well-known/openid-configuration is appended automatically.
Optional — PKCE is always sent, so a public client works. Leave the dots untouched to keep the stored value.
Shown on the login page as “Sign in with …”.
openid is always included.
Claim carrying the user's groups, matched against the mappings on
Groups to assign workgroups.
Usually groups; some Okta setups use roles.
Save first — the probe reads the stored issuer.
Discovery succeeded
Issuer:
Authorize:
Token:
The provider does not advertise a
claim. Group→workgroup mapping may
not work until it is configured to emit one — some providers emit claims they do not
advertise, so this is worth checking rather than assuming broken.
Run several regions in one account? Each region carries its own resource ids (subnets, security groups, SSH secrets, networks). Blank fields fall back to the flat config keys, and the default region always resolves to those — so single-region setups are unchanged. The sandbox auto-populates these when you run its setup script in more than one region.
No region sets configured — every region resolves to the flat defaults.