Skip to main content

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.md at cli.grantflow.cloud/README.md.
  • Optional: Add the compiled grantflow binary 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:

  1. Copy the provided link or open it directly from your terminal output
  2. Enter the code shown (or the link will prefill it)
  3. Select your account in the correct tenant and approve
tip

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 URL
  • tenantId: 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.

Quick Start Commands
# 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
Output formats

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 token
  • grantflow logout — Clear cached tokens
  • grantflow config view [--output json] — Show effective configuration

Roles (user scope)

  • grantflow roles list [--output table|json|yaml] — List roles you can request
  • grantflow roles get <ROLE_ID> — Get a role’s details

Activations (user + approver)

  • grantflow activations list — List your activation requests
  • grantflow activations request <ROLE_ID> --duration <MINUTES> --reason <TEXT> [--account <ACCOUNT_ID>] — Request activation
  • grantflow activations cancel <ACTIVATION_ID> — Cancel a pending request
  • grantflow 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 you
  • grantflow accounts get <ACCOUNT_ID> — Get account details
  • grantflow 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 connectors
  • grantflow admin connectors sync <CONNECTOR_ID> — Trigger a sync
  • grantflow admin agents list — List on‑premises agents
  • grantflow admin jobs list [--limit <N>] [--status pending|running|completed|failed] — List background jobs
  • grantflow 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:

List Role IDs
grantflow roles list --output json | jq -r '.[].id'

Request activation for the first role returned:

Request Activation
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:

Filter Audit Events
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):

Process Roles in Loop
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):

Parallel Queries
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):

Batch Approve
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 Function
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:

Error Handling
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):

  1. Default values
  2. File: ~/.grantflow/config.yaml
  3. Environment variables (prefix GRANTFLOW_)
  4. Flags passed on the command line

Environment variables:

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 logout clears cache and forces re‑auth

Tenant authority and account picker

  • Set tenantId in config (or --tenant-id) to avoid /common loops
  • Optional: add a domain hint to reduce account picker friction (domainHint in 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:

FlagDescription
--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|yamlOutput format (default: table)
--debugEnable debug logging

Exit codes & errors

  • Success returns exit code 0.
  • Any error returns a non‑zero exit code and a concise error message.
  • Add --debug to print more detail (request targets, status codes) for troubleshooting.

Planned (subject to change) exit code mapping for future versions:

CodeMeaning
0Success
1Generic error (default)
2Validation error (bad flags/input)
3Authentication failure (login/consent/tenant)
4Not found (resource missing or out of scope)
5Forbidden (insufficient privileges)
6Rate limited (retry later)
7Server/transport error
note

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 --help or grantflow <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 tenantId in ~/.grantflow/config.yaml or pass --tenant-id <TENANT_ID>.
  • Who approves my activation?
    • Approvers are defined by your organization’s approver policies. Use activations list to see status, or contact your admin.
  • Can I run the CLI non‑interactively?
    • Yes, after initial login, tokens are cached and refreshed silently until they expire or you logout.
  • How do I get raw JSON for scripts?
    • Add --output json to any command; combine with jq as needed.

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)
  • SPA (provider tenant client): 32654b34-df24-4a9b-9261-27f37a66bff9
  • CLI (provider tenant client): 8e29ce44-70fe-405f-8604-3c70c1716d91
note

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.