Steve Friedman
12/17/2025, 10:29 PMMarvin
12/17/2025, 10:29 PMMarvin
12/17/2025, 10:33 PMraw_request if you want to call undocumented endpoints at your own risk.
- Reference: CloudClient reference
- CLI: prefect cloud covers login, selecting a workspace, opening the UI, IP allowlists, and webhooks. It does not manage service accounts, roles, teams, or ACLs.
- Verified commands: prefect cloud login|logout|open|workspace|ip-allowlist|webhook
- YAML: Used for deployments (prefect deploy), not for RBAC.
- Terraform: No official Terraform provider for Prefect Cloud RBAC.
Enterprise features:
- Teams and object-level ACLs (deployments/blocks/work pools) are Enterprise features and are UI-driven today.
- Docs:
- Service accounts: Service accounts
- Roles & permissions: Roles and permissions
- Teams: Teams
- Object ACLs: Object-level ACLs
What you can do programmatically (supported)
- Create/manage deployments and schedules using a service account API key (created in the UI).
- Example: authenticate with a service account and list deployments
import os
from prefect import get_client
os.environ["PREFECT_API_KEY"] = "pnu_xxx" # from a service account created in the UI
os.environ["PREFECT_API_URL"] = "<https://api.prefect.cloud/api/accounts/<acct_id>/workspaces/<ws_id>>"
async def main():
async with get_client() as client:
deployments = await client.read_deployments()
print(f"{len(deployments)} deployments visible to this service account")
# run with: python -m asyncio <this_file>.py
Undocumented workaround (not recommended / may change without notice)
- There are underlying REST endpoints used by the UI for RBAC, but they are not documented or supported for public automation. If you still want to experiment, you can make raw requests via CloudClient.raw_request.
- Strong caveat: contracts can change without notice; no compatibility guarantees or support.
import asyncio
from prefect.client.cloud import get_cloud_client
async def list_service_accounts():
async with get_cloud_client(api_key="pnu_xxx") as client:
# Example path inferred from the UI; not officially supported
resp = await client.raw_request(
"GET",
"accounts/{account_id}/service_accounts",
path_params={"account_id": client.account_id},
)
print(resp.json())
asyncio.run(list_service_accounts())
Notes on “deployments, schedules, etc.”
- Schedules are attached to deployments in Prefect 3.x. Programmatic creation/update of deployments and their schedules is fully supported (via Python/CLI), but who can do that is controlled by your workspace roles and (Enterprise) object ACLs set in the UI.
If you can share which specific RBAC resources and relationships you want to manage as code (e.g., “create a service account, assign it to workspace X with role Y, grant read on deployment Z”), I can:Marvin
12/17/2025, 10:33 PMSteve Friedman
12/17/2025, 10:41 PMMarvin
12/17/2025, 10:41 PMMarvin
12/17/2025, 10:44 PMprefect_account_member.
Minimal example (service account + workspace access + deployment ACL)
```
terraform {
required_providers {
prefect = {
source = "PrefectHQ/prefect"
version = "~> 2.92.0"
}
}
}
provider "prefect" {
account_id = var.account_id
api_key = var.admin_api_key # user or SA with sufficient privileges
}
variable "account_id" {}
variable "admin_api_key" {
sensitive = true
}
# Your target workspace and role IDs (from UI or data sources)
variable "workspace_id" {}
variable "developer_workspace_role_id" {}
variable "deployment_id" {}
# 1) Create a service account for automation
resource "prefect_service_account" "bot" {
name = "terraform-bot"
account_role_name = "Member" # or "Admin" if you need account-wide changes
api_key_expiration = "2026-12-31T235959Z"
}
# 2) Grant the SA a workspace role (e.g., Developer)
resource "prefect_workspace_access" "bot_access" {
accessor_type = "SERVICE_ACCOUNT"
accessor_id = prefect_service_account.bot.id
workspace_id = var.workspace_id
workspace_role_id = var.developer_workspace_role_id
}
# 3) Optional: lock down a deployment with an explicit ACL and grant the SA access
resource "prefect_deployment_access" "bot_deployment_acl" {
workspace_id = var.workspace_id
deployment_id = var.deployment_id
# Grant bot the ability to run/manage this deployment
run_actor_ids = [prefect_service_account.bot.actor_id]
manage_actor_ids = [prefect_service_account.bot.actor_id]
}
output "bot_api_key" {
value = prefect_service_account.bot.api_key
sensitive = true
}Marvin
12/17/2025, 10:44 PM