@rafalpodles/am-cli
v0.1.1
Published
Gravitee Access Management CLI — manage domains, apps, users, and OIDC flows from your terminal
Downloads
36
Maintainers
Readme
Why?
| Without CLI | With CLI |
|---|---|
| Open browser → navigate → click → click → click | am app create --name myapp --type web |
| Copy UUID from URL bar to use in scripts | am app get myapp (works with names) |
| Manually compare staging vs production | am domain copy --to prod --dry-run |
| Ask colleague for their domain config | am domain export -f domain.json |
| No quick way to test OIDC flows | am test login --app myapp --username admin --password admin |
| Debug "is AM even running?" | am health && am doctor |
AI Agent Integration
The CLI ships with SKILL.md — a skill definition that lets AI coding agents use AM CLI commands on your behalf. Works with Claude Code, Cursor, Copilot, and custom agent frameworks.
Claude Code
# Copy the skill to your global skills directory
mkdir -p ~/.claude/skills/gravitee-am
cp SKILL.md ~/.claude/skills/gravitee-am/SKILL.mdThen just ask naturally:
create a web app called "my-portal" with redirect URI on localhost:4200
lock user [email protected]
show me the grant types on my-portal
change token lifetime to 1 hour on my-portal
export the domain config to a file
test ROPC login on my-portal with user admin
what's the AM status?Cursor / Other IDEs
Add SKILL.md to your project context or .cursorrules.
Custom Agents
Use SKILL.md as a tool/function description in your agent framework. The CLI outputs JSON (-o json) for easy parsing, and all commands are non-interactive when flags are provided.
Quick Start
# Install
cd gravitee-am-cli && npm install
# Login (interactive — asks for URL, username, password)
npm run am -- login
# Or non-interactive
npm run am -- login --url http://localhost:8093 --username admin --password admin
# Pick a domain
npm run am -- set domain my-domain
# You're ready
npm run am -- app list
npm run am -- user listTip: For convenience, build and link globally:
npm run build && npm link am login # now works directly
Features at a Glance
Smart Resource Resolution
Forget UUIDs. Use names, client IDs, usernames, or emails — the CLI figures it out.
am app get my-web-app # by name
am app get aB3kR7xWdF # by clientId
am app get 8f3a-...-c2e1 # by UUID — still works
am user lock admin # by username
am user get [email protected] # by emailThree Output Formats
am domain list # pretty table (default)
am domain list -o json # JSON for scripting / jq
am domain list -o compact # key-value pairs# Table output
┌──────────────┬────────────┬──────────┐
│ name │ hrid │ enabled │
├──────────────┼────────────┼──────────┤
│ My Domain │ my-domain │ true │
│ Staging │ staging │ true │
└──────────────┴────────────┴──────────┘Multi-Environment Workspaces
Manage local, staging, and production from the same terminal.
am config set-workspace local --url http://localhost:8093
am config set-workspace staging --url https://am-staging.example.com --org myorg
am config set-workspace prod --url https://am.example.com --org myorg
am config use-workspace staging
am login
am domain list # lists staging domains
am config use-workspace prod
am login
am domain list # lists production domainsCross-Environment Operations
# Copy a domain from staging to production (with preview)
am config use-workspace staging
am set domain my-domain
am domain copy --to prod --dry-run
am domain copy --to prod
# Export / import
am domain export -f domain.json
am config use-workspace prod
am domain import domain.jsonInteractive & Non-Interactive Modes
Every create/update command works both ways:
# Interactive — prompts for every field
am app create
# Non-interactive — perfect for scripts
am app create --name myapp --type web --redirect-uris http://localhost:3000/callbackCI/CD Ready
Environment variables replace all interactive configuration:
export AM_URL=https://am.example.com
export AM_TOKEN=eyJhbGciOi...
export AM_DOMAIN=my-domain
# Now every command works without login or context setup
am app list -o json
am user list -o json | jq '.[] | .username'Built-in OIDC Testing
Test OAuth2/OIDC flows directly from the terminal:
# Check OIDC discovery
am test discover
# Test Resource Owner Password Credentials flow (confidential client)
am test login --app <clientId> --secret <clientSecret> --username user --password pass
# Test Resource Owner Password Credentials flow (public client)
am test login --app <clientId> --username user --password pass
# Test Client Credentials flow
am test client-credentials --app <clientId> --secret <clientSecret>
# Output includes decoded JWT, issuer validation, expiry check
# Tip: make sure your app has an IdP assigned (am app update myapp --idp <idp-id>)Diagnostics & Debugging
am status # current context at a glance
am health # is AM reachable?
am health --gateway http://localhost:8092
am doctor # full config & connectivity check
am logs # tail audit logs live
am logs --type USER_LOGIN --status FAILURE
# Debug mode — see every HTTP request
am --verbose app list
# [debug] GET http://localhost:8093/management/organizations/DEFAULT/...
# [debug] 200 http://localhost:8093/... (42ms)Full Command Reference
Authentication
| Command | Description |
|---|---|
| am login | Interactive login (URL + credentials) |
| am login --url <url> --username <u> --password <p> | Non-interactive login |
| am login --url <url> --token <token> | Service account token login |
| am logout | Clear token for current workspace |
| am logout --all | Clear all stored tokens |
| am whoami | Show authenticated user info |
Context
| Command | Description |
|---|---|
| am set domain <idOrName> | Set active domain (by ID, HRID, or name) |
| am set domain --clear | Unset current domain |
| am get domain | Show current domain |
| am status | Full context overview |
Domains
| Command | Description |
|---|---|
| am domain list [--all] [-q <query>] | List domains (paginated or all) |
| am domain get [id] | Get domain details |
| am domain create [--name <n>] | Create domain (interactive or flags) |
| am domain enable [id] | Enable a domain |
| am domain disable [id] | Disable a domain |
| am domain delete <id> [-f] | Delete domain (with confirmation) |
| am domain export [-f <file>] | Export full domain config to JSON |
| am domain import <file> [--target <id>] [--dry-run] | Import domain from JSON |
| am domain copy --to <workspace> [--dry-run] | Copy domain across workspaces |
Applications
| Command | Description |
|---|---|
| am app list [--all] [-q <query>] | List applications |
| am app get <idOrName> | Get app by ID, clientId, or name |
| am app create [--name <n> --type <t>] | Create app (interactive or flags) |
| am app update <idOrName> [--name] [--enabled] [--idp <ids>] | Update application or assign IdPs |
| am app delete <idOrName> [-f] | Delete application |
| am app settings <idOrName> | View OAuth2/OIDC settings |
| am app settings <idOrName> --grant-types <types> | Update grant types |
| am app settings <idOrName> --token-lifetime <sec> | Set token lifetimes |
Users
| Command | Description |
|---|---|
| am user list [--all] [-q <query>] [--filter <scim>] | List users |
| am user get <idOrName> | Get user by ID, username, or email |
| am user create [--username <u>] | Create user |
| am user update <idOrName> [--email] [--enabled] | Update user |
| am user lock <idOrName> | Lock user account |
| am user unlock <idOrName> | Unlock user account |
| am user reset-password <idOrName> | Reset password |
| am user delete <idOrName> [-f] | Delete user |
Roles & Scopes
| Command | Description |
|---|---|
| am role list [--all] | List roles |
| am role get <id> | Get role details |
| am role create [--name <n> --type <t>] | Create role (DOMAIN or APPLICATION) |
| am scope list [--all] | List OAuth2 scopes |
| am scope get <id> | Get scope details |
| am scope create [--key <k> --name <n>] | Create scope |
Identity Providers, Certificates, Factors, Groups, Flows
| Command | Description |
|---|---|
| am idp list / am idp get <id> | Identity providers |
| am certificate list / get / delete | Certificates |
| am factor list / am factor get <id> | MFA factors |
| am group list / get / create / delete | Groups |
| am flow list / am flow get <id> | Authentication flows |
Audit Logs
| Command | Description |
|---|---|
| am audit list [--type <t>] [--status <s>] [--from <date>] [--to <date>] | List events |
| am audit get <id> | Get event details |
| am logs [-f] [--type <t>] [--status <s>] | Tail logs in real-time |
Tokens (Service Accounts)
| Command | Description |
|---|---|
| am token create <userId> [--name <n>] | Create access token |
| am token list <userId> | List tokens |
| am token revoke <userId> <tokenId> [-f] | Revoke a token |
Plugins (Schema-Driven)
| Command | Description |
|---|---|
| am plugin list <type> | List available plugins (idp, factor, certificate, ...) |
| am plugin schema <type> <pluginId> | Show configuration schema |
| am plugin create <type> <pluginId> | Create instance from schema (interactive) |
OIDC Testing
| Command | Description |
|---|---|
| am test discover | Fetch OIDC discovery document |
| am test login [--app <clientId>] [--username <u>] | Test ROPC flow |
| am test client-credentials [--app <clientId>] [--secret <s>] | Test client_credentials |
Configuration & Workspaces
| Command | Description |
|---|---|
| am config set-workspace <name> --url <url> | Create/update workspace |
| am config use-workspace <name> | Switch workspace |
| am config delete-workspace <name> | Remove workspace |
| am config list | List all workspaces |
| am config current | Show current context |
| am config set-default-output <format> | Set default output (table/json/compact) |
| am config path | Show config file location |
Diagnostics
| Command | Description |
|---|---|
| am status | CLI context and session status |
| am health [--gateway <url>] | Check AM reachability |
| am doctor | Full configuration diagnosis |
| am support-dump [-f <file>] [--all-domains] | Generate diagnostic dump |
Shell & Completion
| Command | Description |
|---|---|
| am shell | Interactive REPL (with tab completion) |
| am completion bash\|zsh\|fish | Generate shell completion script |
Global Options
| Flag | Description |
|---|---|
| -o, --output <format> | Output format: table (default), json, compact |
| --domain <id> | Override current domain for this command |
| --workspace <name> | Override current workspace for this command |
| --verbose | Log HTTP requests, responses, and timing |
| -V, --version | Show CLI version |
| -h, --help | Show help |
Environment Variables
For CI/CD pipelines and automation — these override stored config entirely:
| Variable | Description | Replaces |
|---|---|---|
| AM_URL | Management API base URL | am config set-workspace |
| AM_TOKEN | Bearer token | am login |
| AM_DOMAIN | Domain ID | am set domain |
| AM_ORG | Organisation ID (default: DEFAULT) | --org flag |
| AM_ENV | Environment ID (default: DEFAULT) | --env flag |
GitHub Actions Example
jobs:
deploy:
runs-on: ubuntu-latest
env:
AM_URL: ${{ secrets.AM_URL }}
AM_TOKEN: ${{ secrets.AM_TOKEN }}
AM_DOMAIN: my-domain
steps:
- uses: actions/checkout@v4
- run: npm ci --prefix gravitee-am-cli
- run: |
cd gravitee-am-cli
# Export current config
npm run am -- domain export -f current.json
# List applications as JSON
npm run am -- app list -o json --all > apps.jsonRecipes
Bulk export all domains
am domain list --all -o json | jq -r '.[].id' | while read id; do
am domain export "$id" -f "export-${id}.json"
doneFind all disabled applications
am app list --all -o json | jq '.[] | select(.enabled == false) | .name'Lock all users matching a pattern
am user list --all -o json | jq -r '.[] | select(.email | test("@old-domain.com$")) | .id' | while read id; do
am user lock "$id"
doneCompare application settings between environments
diff <(am --workspace staging app settings myapp -o json) \
<(am --workspace prod app settings myapp -o json)Generate a support dump for all domains
am support-dump --all-domains -f full-dump.json
# Secrets are redacted by default. Use --no-redact for raw output (caution!).Full ROPC (password grant) flow from scratch
# 1. Create an application
am app create --name my-ropc-app --type web --redirect-uris http://localhost:3000/callback
# → Note the Client ID and Client Secret from the output
# 2. Set grant type to password
am app settings my-ropc-app --grant-types password
# 3. Assign an identity provider (required for ROPC)
am idp list # find the IdP ID
am app update my-ropc-app --idp <idp-id>
# 4. Create a test user
am user create --username testuser --password 'MyPassword123!'
# 5. Test the flow
am test login --app <clientId> --secret <clientSecret> --username testuser --password 'MyPassword123!'
# ✓ Token obtained successfully
# Access Token: eyJraWQiOi...Quick OIDC checks
am test discover # verify OIDC discovery
am test client-credentials --app my-service --secret s3cret # machine-to-machineConfiguration
The CLI stores configuration in ~/.gravitee-am/config.json with secure file permissions (0600).
~/.gravitee-am/
config.json # workspaces, tokens, preferencesThe config file contains:
- Workspaces — named environments (URL, org, env)
- Auth tokens — stored per workspace (with expiry tracking)
- Defaults — preferred output format
- Current context — active workspace and domain
Tokens expire automatically. The CLI warns you 5 minutes before expiry and shows clear error messages when re-authentication is needed.
Architecture (for contributors)
bin/am.ts # Entry point, command registration, help text
src/
auth/
auth.ts # Login, token storage, logout
token-refresh.ts # Token validity checking, expiry warnings
commands/
app/index.ts # am app *
user/index.ts # am user *
domain/index.ts # am domain *
... # One file per command group
config/
config-manager.ts # ~/.gravitee-am/ persistence, require* guards
output/
formatter.ts # Table/JSON/compact output, resource detection
sdk/
client.ts # OpenAPI SDK client factory with caching
utils/
api-error.ts # Unified API error handling
cli-error.ts # Typed CLI errors (replaces process.exit)
command-context.ts # Shared context extraction (getContext/getDomainContext)
debug.ts # --verbose request/response logging
pagination.ts # Universal paginated fetch
resolvers.ts # Smart ID/name/email resolution
retry.ts # Exponential backoff for transient failures
schema-parser.ts # Plugin schema → interactive prompts
spinner.ts # TTY-aware progress spinners
version.ts # Version from package.json
test/
*.test.ts # Jest unit tests (266 tests, 16 suites)Key Design Decisions
- Commander.js for argument parsing — industry standard, excellent help generation
- OpenAPI SDK reused from
gravitee-am-test-sdk— type-safe API calls, always in sync - Smart resolution — commands accept human-friendly identifiers, resolved via try-ID-then-search
- CliError over process.exit — throwable errors enable clean shell mode and testability
- Client caching — API clients cached per (workspace, token) to avoid re-creation overhead
- Retry with backoff — transient failures (502/503/504, timeouts) retried automatically in bulk operations
- TTY-aware output — spinners and colours only when output is a terminal, not when piped
Development
# Install dependencies
npm install
# Run in development (no build step)
npm run am -- <command>
# Run tests
npm test
# Run tests with coverage
npx jest --coverage
# Type check
npm run typecheck
# Build for distribution
npm run buildRequirements
- Node.js >= 20.11.1
- A running Gravitee AM instance (Management API)
