GrantFlow CLI
Meet the GrantFlow CLI: a fast, scriptable way to work with GrantFlow from your terminal.
What you can do
- Authenticate with your Entra ID tenant (device code flow)
- List and manage roles, activations, and accounts
- Pipe JSON into your favorite tools for automation
Install
- Build from source (recommended for power users): see the CLI repo
README.mdatcli.grantflow.cloud/README.md. - Optional: Add the compiled
grantflowbinary to your PATH.
Authenticate (device code)
The CLI uses Entra ID device code flow. When you run a command that needs a token, you’ll see a one‑time code and a sign‑in URL.
Steps:
- Copy the provided link or open it directly from your terminal output
- Enter the code shown (or the link will prefill it)
- Select your account in the correct tenant and approve
If you’re an admin configuring this for a new customer tenant, complete the setup in “Customer tenant Entra setup” first, then return here.
Tokens are cached in ~/.grantflow/token-cache.json and refreshed automatically.
Config
The CLI looks for a YAML config at ~/.grantflow/config.yaml.
Example:
# ~/.grantflow/config.yaml
apiBaseUrl: https://api.grantflow.cloud
# Optional: force tenant authority for auth flows
tenantId: 00000000-0000-0000-0000-000000000000
# Optional: domain hint for the account picker UX
# domainHint: contoso.com
apiBaseUrl: Your GrantFlow API base URLtenantId: Forces auth against a specific tenant authority (recommended)domainHint: Hints the account picker to your domain (less chance of picking the wrong account)
Quick start examples
Below are copy‑paste examples you can run right away. Add --output json to pipe into tools like jq.
# Authenticate and cache a token
grantflow login
# List your eligible roles
grantflow roles list --output table
# Get details for a specific role
grantflow roles get <ROLE_ID> --output json
# Request a JIT activation (60 minutes)
grantflow activations request <ROLE_ID> --duration 60 --reason "Routine maintenance"
# Check your activation requests
grantflow activations list --output table
# List privileged accounts you can check out
grantflow accounts list --output json | jq '.[].name'
# Check out an account for 30 minutes (requires a reason)
grantflow accounts checkout <ACCOUNT_ID> --duration 30 --reason "Break-glass access"
# View recent audit events (limit 20)
grantflow audit list --limit 20 --output table
Use --output table|json|yaml at any command level (defaults to table).
Command catalog
High‑level overview of available commands. Use --help on any command for full usage.
Auth and config
grantflow login— Authenticate via device code flow and cache tokengrantflow logout— Clear cached tokensgrantflow config view [--output json]— Show effective configuration
Roles (user scope)
grantflow roles list [--output table|json|yaml]— List roles you can requestgrantflow roles get <ROLE_ID>— Get a role’s details
Activations (user + approver)
grantflow activations list— List your activation requestsgrantflow activations request <ROLE_ID> --duration <MINUTES> --reason <TEXT> [--account <ACCOUNT_ID>]— Request activationgrantflow activations cancel <ACTIVATION_ID>— Cancel a pending requestgrantflow activations approve <ACTIVATION_ID> [--comment <TEXT>]— Approve (requires approver role)grantflow activations deny <ACTIVATION_ID> --reason <TEXT>— Deny (requires approver role)
Accounts (user scope)
grantflow accounts list— List privileged accounts available to yougrantflow accounts get <ACCOUNT_ID>— Get account detailsgrantflow accounts checkout <ACCOUNT_ID> --duration <MINUTES> --reason <TEXT>— Temporary checkout
Audit (read‑only)
grantflow audit list [--limit <N>] [--action <NAME>] [--actor <USER_ID>]— Search audit events
Admin (requires admin role)
grantflow admin connectors list— List identity connectorsgrantflow admin connectors sync <CONNECTOR_ID>— Trigger a syncgrantflow admin agents list— List on‑premises agentsgrantflow admin jobs list [--limit <N>] [--status pending|running|completed|failed]— List background jobsgrantflow admin roles list— List all roles (admin view)grantflow admin roles create --name <NAME> --description <TEXT> --type entraid|activedirectory --connector <CONNECTOR_ID> [--max-duration <MINUTES>]— Create a role
Scripting & automation
JSON processing with jq
List role IDs:
grantflow roles list --output json | jq -r '.[].id'
Request activation for the first role returned:
RID=$(grantflow roles list --output json | jq -r '.[0].id')
grantflow activations request "$RID" --duration 45 --reason "Batch job"
Filter audit events by action and actor:
grantflow audit list --limit 200 --action ActivationApproved --output json \
| jq -r '.[] | select(.actor=="alice@contoso.com") | [.timestamp, .action, .resourceId] | @tsv'
Pipelines and batching
Process items in a loop (with simple progress):
set -euo pipefail
echo "Listing roles..." >&2
grantflow roles list --output json \
| jq -r '.[].id' \
| while read -r RID; do
echo "→ Role: $RID" >&2
grantflow roles get "$RID" --output json | jq '{id, name, maxDuration}'
done | jq -s '.'
Parallelize read‑only queries with xargs (tune -P for concurrency):
grantflow roles list --output json \
| jq -r '.[].id' \
| xargs -I {} -P 4 sh -c 'grantflow roles get "$1" --output json' -- {}
Batch approve activations from a CSV (id,comment):
while IFS=, read -r AID COMMENT; do
grantflow activations approve "$AID" --comment "$COMMENT"
done < approvals.csv
Error handling & retry
Most commands return non‑zero on error. For transient errors (e.g., HTTP 429), add a small backoff:
retry() {
local tries=${1:-5} delay=${2:-2}
shift 2
local n=1
until "$@"; do
if (( n >= tries )); then
echo "Command failed after $tries attempts" >&2
return 1
fi
sleep $((delay * n))
n=$((n+1))
done
}
# Example: list audit events with retry
retry 5 2 grantflow audit list --limit 100 --output json > audit.json
Check exit status explicitly and handle gracefully:
if ! grantflow activations request "$RID" --duration 30 --reason "Ops"; then
echo "Activation request failed; check your role eligibility and reason." >&2
exit 1
fi
Config precedence and env vars
The CLI loads config from (lowest → highest precedence):
- Default values
- File:
~/.grantflow/config.yaml - Environment variables (prefix
GRANTFLOW_) - Flags passed on the command line
Environment variables:
export GRANTFLOW_API_URL=https://api.grantflow.cloud
export GRANTFLOW_TENANT_ID=<TENANT_ID>
export GRANTFLOW_CLIENT_ID=<CLIENT_ID>
export GRANTFLOW_SCOPE="api://06b7f2b0-c048-4243-80c4-60d0f1bce15e/.default"
export GRANTFLOW_OUTPUT=json
export GRANTFLOW_DEBUG=true
Advanced topics
Token cache
- Location:
~/.grantflow/token-cache.json - Device code flow tokens refresh automatically when possible
grantflow logoutclears cache and forces re‑auth
Tenant authority and account picker
- Set
tenantIdin config (or--tenant-id) to avoid/commonloops - Optional: add a domain hint to reduce account picker friction (
domainHintin config)
Rate limiting and retries
- The CLI surfaces API rate‑limit responses (HTTP 429). If encountered, wait and retry.
- For scripts, add simple backoff loops around calls that may hit rate limits.
Global flags
These flags can be specified at the root or any subcommand:
| Flag | Description |
|---|---|
--config <path> | Use an alternate config file (default: ~/.grantflow/config.yaml) |
--api-url <url> | Override API base URL |
--tenant-id <uuid> | Force Azure tenant authority |
--client-id <uuid> | Override Azure client ID (for custom tenants) |
--scope <scope> | OAuth2 scope (default: api://<client-id>/.default) |
--output table|json|yaml | Output format (default: table) |
--debug | Enable debug logging |
Exit codes & errors
- Success returns exit code
0. - Any error returns a non‑zero exit code and a concise error message.
- Add
--debugto print more detail (request targets, status codes) for troubleshooting.
Planned (subject to change) exit code mapping for future versions:
| Code | Meaning |
|---|---|
| 0 | Success |
| 1 | Generic error (default) |
| 2 | Validation error (bad flags/input) |
| 3 | Authentication failure (login/consent/tenant) |
| 4 | Not found (resource missing or out of scope) |
| 5 | Forbidden (insufficient privileges) |
| 6 | Rate limited (retry later) |
| 7 | Server/transport error |
Today the CLI returns 0 on success and non‑zero on error. The specific codes above are reserved for a future release to improve scripting ergonomics.
Common commands
- List roles:
grantflow roles list - List accounts:
grantflow accounts list - Help:
grantflow --helporgrantflow <command> --help
Most list commands support pagination via flags (e.g., --limit, --offset) when available. Output is JSON by default; you can pipe through jq.
FAQ
- How do I switch tenants?
- Set
tenantIdin~/.grantflow/config.yamlor pass--tenant-id <TENANT_ID>.
- Set
- Who approves my activation?
- Approvers are defined by your organization’s approver policies. Use
activations listto see status, or contact your admin.
- Approvers are defined by your organization’s approver policies. Use
- Can I run the CLI non‑interactively?
- Yes, after initial
login, tokens are cached and refreshed silently until they expire or youlogout.
- Yes, after initial
- How do I get raw JSON for scripts?
- Add
--output jsonto any command; combine withjqas needed.
- Add
Troubleshooting
- You finish browser auth but the CLI keeps waiting
- Ensure the tenant is correct and setup is complete (admin consent granted)
- If you see a redirect to “/common”, make sure the CLI is configured with
tenantId
- “Not authorized” errors
- An admin must grant the CLI app access to the pamplus API scope in your tenant
- See the setup guide below
- Empty lists
- Usually means no data in that scope yet; verify your tenant and filters
Reference IDs (current provider tenant)
These are the canonical IDs in the provider environment. You will create per‑tenant client apps in customer tenants during onboarding.
- API (resource):
- Application (client) ID:
06b7f2b0-c048-4243-80c4-60d0f1bce15e - Scope:
api://06b7f2b0-c048-4243-80c4-60d0f1bce15e/user_impersonation(f4365de7-6ca4-4619-beab-f98682a96f93)
- Application (client) ID:
- SPA (provider tenant client):
32654b34-df24-4a9b-9261-27f37a66bff9 - CLI (provider tenant client):
8e29ce44-70fe-405f-8604-3c70c1716d91
The SPA and CLI registrations in the provider tenant are single‑tenant (AzureADMyOrg). For customers, you’ll create equivalent client apps in their tenant pointing to the same GrantFlow API resource.
See also
- Customer tenant setup: ../admin-guides/customer-tenant-entra-setup.md
- GrantFlow API endpoints: refer to your internal API docs or Bruno collection
Planning for growth
As the CLI reaches ~30+ commands, consider migrating to a dedicated CLI Reference section (/docs/cli-reference/) with setup, user/admin commands, guides, and reference subsections. This preserves a simple onboarding quick‑start here while offering a scalable reference taxonomy.