DevCLI reference
DevCLI is the aigw command-line tool for managing AIGW configuration. Install it and log in before running these commands.
After creating the Resource, create or verify its signing key. Give the per-resource issuer and populated JWKS URL to the merchant IAM administrator, then verify authorization and redemption.
Commands and permissions
| Task | Command | API key permission |
|---|---|---|
| Save a management API key | aigw login | project:read to validate the key |
| Check the saved login | aigw status -o json | project:read |
| Remove the saved login | aigw logout | None |
| Show the installed version | aigw version -o json | None |
| List Projects | aigw projects list | project:read |
| Read a Project | aigw projects get PROJECT_ID | project:read |
| Create a Project | aigw projects create --name "My project" | project:write |
| List Resources | aigw resources list --project-id PROJECT_ID | project:read |
| Read a Resource | aigw resources get RESOURCE_ID --project-id PROJECT_ID | project:read |
| Create a Resource | aigw resources create --project-id PROJECT_ID … | project:write |
| Update a Resource | aigw resources update RESOURCE_ID --project-id PROJECT_ID … | project:write |
| Read exposed scopes | aigw resources scopes list --project-id PROJECT_ID --resource-id RESOURCE_ID | project:read |
| Read Project agent policy | aigw projects agent-policy get --project-id PROJECT_ID | project:read |
| Update Project agent policy | aigw projects agent-policy update --project-id PROJECT_ID … | project:write |
| List Proxy clients | aigw projects proxy-clients list --project-id PROJECT_ID | project:read |
| Create a Proxy client | aigw projects proxy-clients create --project-id PROJECT_ID --secret-file PATH | project:write |
| Revoke a Proxy client | aigw projects proxy-clients revoke PROXY_CLIENT_ID --project-id PROJECT_ID | project:write |
| List signing keys | aigw resources signing-keys list --project-id PROJECT_ID --resource-id RESOURCE_ID | project:read |
| Create a signing key | aigw resources signing-keys create --project-id PROJECT_ID --resource-id RESOURCE_ID | project:write |
| Print the coding-assistant skill | aigw skill show | None |
| Install or update the Claude Code skill | aigw skill install | None |
| Remove the Claude Code skill | aigw skill uninstall | None |
PROJECT_ID, RESOURCE_ID, and PROXY_CLIENT_ID are the identifiers returned by the corresponding create or list command. … indicates additional fields described below. Use aigw --help to browse other command groups, or append --help to any command for its installed-version usage.
Common flags
| Flag | Commands | Use |
|---|---|---|
--project-id ID | Resource, policy, signing-key, and Proxy-client commands | Required Project identifier |
--resource-id ID | Resource subcommands, including scopes and signing keys | Required Resource identifier; resources get/update/replace/delete take it as a positional argument instead |
--name TEXT | Project and Resource create/update | Display name; required when creating |
--type PROXY | projects create | Optional; PROXY is the default and supported Project type |
-d, --data 'FIELD=VALUE' | Commands with request fields | Repeat for nested fields and arrays; see nested data |
-o, --output json | API commands, status, version | API commands output JSON by default; status and version default to text |
--secret-file PATH | Commands that issue a one-time secret | Save the returned secret to a new file instead of including it in stdout |
--confirm | Delete and revoke commands | Skip the interactive confirmation; required for those commands in scripts |
--api-key KEY | API commands | Override the login for one command; prefer aigw login or AIGW_API_KEY to keep secrets out of command history |
-h, --help | All commands | Show usage without sending an API request |
API commands return JSON on stdout; prompts and warnings go to stderr. Credentials are selected in this order: --api-key, AIGW_API_KEY, then the saved login. Use aigw status -o json to check keySource.
Login flags
| Flag | Use |
|---|---|
--with-key-stdin | Read the API key from standard input instead of the interactive prompt |
--confirm | Replace an existing saved login without asking; required when replacing it non-interactively |
--insecure-storage | Save the key in a plaintext file instead of the operating system's credential store. Use only when the credential store is unavailable and you can protect the file |
For CI, prefer a masked AIGW_API_KEY secret as described in Scripts and CI.
Coding-assistant skill commands
| Command | Flags | Result |
|---|---|---|
aigw skill show | --body | Print the skill; --body prints instructions without Claude Code frontmatter or the installation note |
aigw skill install | --confirm | Install or update the Claude Code skill; --confirm permits replacement of an existing skill file not created by DevCLI |
aigw skill uninstall | --confirm | Remove the Claude Code skill; --confirm permits removal of a skill file not created by DevCLI |
Claude Code's default skill directory is ~/.claude/skills/aigw. If CLAUDE_CONFIG_DIR is set, the directory is $CLAUDE_CONFIG_DIR/skills/aigw. Run aigw skill install after upgrading DevCLI, then open a new Claude Code session. For Codex setup, follow Use with Codex or Claude Code.
Register a merchant Resource
The examples below use Bash/Zsh. In PowerShell, assign variables as $PROJECT_ID = 'your-project-id' and place each command on one line instead of using \ line continuations.
Prerequisites: an existing Project, a merchant authorization server and reserved client registration, and agreed issuer, token endpoint, client ID, globally unique Resource indicator, and scopes. See Configure your authorization server.
This example uses the JWT bearer grant with PRIVATE_KEY_JWT. Replace every example URL and client ID with values from the merchant IAM owner. Use a provider enabled for your Account; google below is an example.
PROJECT_ID='your-project-id'
aigw resources create \
--project-id "$PROJECT_ID" \
--name "Acme Search API" \
--kind EXCHANGE \
--exchange.indicator "https://mcp.example.com/mcp" \
--exchange.issuer "https://id.example.com/realms/merchant" \
--exchange.token-endpoint "https://id.example.com/realms/merchant/protocol/openid-connect/token" \
--exchange.client-id "aigw-search" \
--exchange.auth-method PRIVATE_KEY_JWT \
--idps google \
-d 'scopes[0][value]=search:read' \
-d 'scopes[0][displayName]=Search products' \
-d 'scopes[0][description]=Find products in the catalog'
Read the returned Resource back with aigw resources get RESOURCE_ID --project-id "$PROJECT_ID". Verify the merchant issuer, indicator, scopes, and identity provider. Registration does not prove that merchant user mapping or token exchange works.
The DevCLI uses EXCHANGE for the Console's Token exchange Resource kind. Its PRIVATE_KEY_JWT / TOKEN_EXCHANGE choices describe the merchant-side integration, not an agent's own OAuth client authentication. See the flags and nested fields below.
Resource creation flags
For aigw resources create, set --project-id, --name, and the fields for the selected Resource kind.
| Flag | When to use it | Value |
|---|---|---|
--kind | Select the integration | EXCHANGE for merchant access; OAUTH_CLIENT for application sign-in |
--idps | Select sign-in providers enabled for your Account | Provider name; repeat the flag for multiple providers |
--exchange.indicator | Required for EXCHANGE | Globally unique Resource indicator, such as https://mcp.example.com/mcp |
--exchange.issuer | Required for EXCHANGE | Merchant authorization-server issuer |
--exchange.token-endpoint | Required for EXCHANGE | Merchant token endpoint URL |
--exchange.client-id | Required for EXCHANGE | Merchant-side client ID |
--exchange.auth-method | Select the merchant-token request pattern | PRIVATE_KEY_JWT or TOKEN_EXCHANGE; standalone CLIENT_SECRET_BASIC is Coming soon |
--exchange.send-resource-param | Optional for TOKEN_EXCHANGE | true (default) sends the indicator as resource; use --exchange.send-resource-param=false to omit it |
--exchange.audience | Optional for TOKEN_EXCHANGE | Merchant-specific audience parameter |
--exchange.subject-token-type | Optional for TOKEN_EXCHANGE | Override the subject token type only if required by the merchant server |
--exchange.actor-client-id | Optional for TOKEN_EXCHANGE | Merchant service-account client ID used to obtain an actor token |
--exchange.actor-client-secret | With an actor client ID | Matching service-account secret |
--exchange.client-secret | Optional for TOKEN_EXCHANGE | Merchant client secret for HTTP Basic authentication, for example with Auth0. Omit it to authenticate with a signed client assertion. |
--oauth-client.redirect-uris | Required for OAUTH_CLIENT | Absolute HTTPS callback; repeat for multiple callbacks |
--oauth-client.scopes | Optional for OAUTH_CLIENT | Repeat for openid, profile, email, phone, or offline_access; openid is always included |
--oauth-client.token-endpoint-auth-method | Optional for OAUTH_CLIENT | CLIENT_SECRET_BASIC (default), CLIENT_SECRET_POST, or NONE for a public client with PKCE |
The OAUTH_CLIENT authentication methods apply to application sign-in. The Coming soon status above applies only to standalone merchant-token provisioning on an EXCHANGE Resource.
Nested fields and arrays
Use a separate -d 'FIELD=VALUE' for each field. Brackets select nested objects or array elements; array indexes start at 0. The three scopes[0] entries in the creation example describe one scope:
{
"scopes": [
{
"value": "search:read",
"displayName": "Search products",
"description": "Find products in the catalog"
}
]
}
To add another scope in the same request, use scopes[1][value], scopes[1][displayName], and scopes[1][description]. value is the scope identifier; the display name and description provide consent-screen text.
Nested object fields work the same way: -d 'exchange[audience]=catalog-api' sets the same field as --exchange.audience catalog-api. Use one form per field; combining both is rejected. Quote each complete FIELD=VALUE argument so the shell preserves brackets and spaces. Values are converted to the field's expected type, such as a boolean for exchange[sendResourceParam].
For string arrays, repeat the named flag, for example --idps google --idps microsoft, using provider names enabled for your Account. Do not combine provider names into a single comma-separated value.
Create the Resource signing key
Creating a Resource with the DevCLI does not create its signing key. Copy the returned Resource ID, then check whether a key already exists:
RESOURCE_ID='your-resource-id'
aigw resources signing-keys list \
--project-id "$PROJECT_ID" --resource-id "$RESOURCE_ID"
If the list has no key, create one and read the list back:
aigw resources signing-keys create \
--project-id "$PROJECT_ID" --resource-id "$RESOURCE_ID"
aigw resources signing-keys list \
--project-id "$PROJECT_ID" --resource-id "$RESOURCE_ID"
Verify an active key and confirm its kid appears in the Resource JWKS keys array before configuring merchant trust. Reuse an existing active key; do not generate a new key on every setup run. See Signing keys for the public-key URL and validation rules.
Create the MCP server's Proxy client
Use the same Project as the merchant Resource:
mkdir -p "$HOME/.config/aigw/app-secrets"
chmod 700 "$HOME/.config/aigw/app-secrets"
aigw projects proxy-clients create \
--project-id "$PROJECT_ID" \
--secret-file "$HOME/.config/aigw/app-secrets/acme-mcp-proxy.secret"
Save the returned client ID in backend configuration. The client secret is written to the new file, rather than printed in the JSON response. It is not retrievable later; the file must not already exist. The DevCLI uses mode 0600 on macOS/Linux; on Windows, protect its directory using your user permissions.
Continue with Get a merchant access token. Your MCP backend uses the Proxy client for client_credentials; it does not send the Console API key to the agent.
Update configuration without replacing everything
Prefer update when you only want to change named top-level fields. A nested object such as exchange replaces that whole object: read it first and preserve its other values. For a name-only change:
aigw resources update RESOURCE_ID --project-id "$PROJECT_ID" --name "Acme Product Search"
aigw resources get RESOURCE_ID --project-id "$PROJECT_ID"
resources replace resets omitted fields; KYA issuer list replacement can clear entries. Read the current state before replace or set. These operations do not use a delete prompt.
Require agent review
Without a configured Agent policy, every agent is approved when it first requests a Resource. Set review rules before accepting requests if operator approval is required. User authorization and scope checks still apply.
Requires project:write for updates and project:read for inspection.
| Flag | Decision it controls | Allowed values |
|---|---|---|
--default-decision | Unverified agents | APPROVE, PENDING, REJECT |
--platform | Platform-trusted agents | APPROVE, PENDING, REJECT |
--wba | Web Bot Auth proof | APPROVE, PENDING, REJECT |
--rdns | Reverse DNS proof | APPROVE, PENDING, REJECT |
--kya | Accepted KYA credential | APPROVE, PENDING, REJECT |
--cimd | Client metadata served from the agent's domain | APPROVE, PENDING, REJECT |
Supply --project-id and at least one decision flag. PENDING corresponds to Hold in the Console and places the agent in Pending. Inspect the current rules first. To hold unverified agents:
aigw projects agent-policy get --project-id "$PROJECT_ID"
aigw projects agent-policy update --project-id "$PROJECT_ID" --default-decision PENDING
aigw projects agent-policy get --project-id "$PROJECT_ID"
This changes access decisions for Resources inheriting that policy. A proof rule cannot be stricter than the unverified-agent default: REJECT is stricter than PENDING, which is stricter than APPROVE. With --default-decision PENDING, each proof rule must be PENDING or APPROVE. Update any conflicting rules in the same command.
To require review under the default and every proof rule:
aigw projects agent-policy update \
--project-id "$PROJECT_ID" \
--default-decision PENDING \
--platform PENDING --wba PENDING --rdns PENDING \
--kya PENDING --cimd PENDING
aigw projects agent-policy get --project-id "$PROJECT_ID"
Domain rules and manual decisions still take precedence. See Agent policy for when changes take effect.
Use in scripts and CI
Configure AIGW_API_KEY as a masked CI secret and expose it to the job:
set -eu
: "${AIGW_API_KEY:?Set AIGW_API_KEY in your CI secret settings}"
aigw status -o json
aigw projects list > aigw-projects.json
Check exit status before consuming JSON:
| Exit code | Meaning | Next action |
|---|---|---|
0 | Success | Read the result |
1 | Input, network, not-found, or another error | Inspect stderr and the command's help |
3 | Missing or rejected authentication | Log in or check injected credentials |
4 | Key lacks a permission | Use a key with the scope named by the error |
Destructive API operations require --confirm without an interactive terminal. Supply it only for an explicitly approved target. When finished, remove an injected key from your terminal with unset AIGW_API_KEY (PowerShell: Remove-Item Env:AIGW_API_KEY). Use aigw logout to remove a saved login. Neither action revokes the key in the Console.
Install without Homebrew
Download the ZIP for your OS and CPU, plus checksums.txt, from GitHub releases. Use files from the same release. The commands below install v0.2.0; replace the version when installing another release.
Linux x86-64
In a new working directory:
curl -fLO https://github.com/loginid1/loginid-aigw-cli/releases/download/v0.2.0/aigw_0.2.0_linux_amd64.zip
curl -fLO https://github.com/loginid1/loginid-aigw-cli/releases/download/v0.2.0/checksums.txt
sha256sum --ignore-missing -c checksums.txt
Continue only when the ZIP reports OK:
unzip aigw_0.2.0_linux_amd64.zip
mkdir -p "$HOME/.local/bin"
install -m 755 aigw "$HOME/.local/bin/aigw"
export PATH="$HOME/.local/bin:$PATH"
aigw version
For arm64, use linux_arm64 in the ZIP URL and filename. Add ~/.local/bin to your shell's startup configuration if needed for future terminals.
Windows PowerShell
Download aigw_0.2.0_windows_amd64.zip and checksums.txt into a new directory. Use windows_arm64 for an arm64 PC.
$zip = "aigw_0.2.0_windows_amd64.zip"
$entry = @(Get-Content checksums.txt | Where-Object { ($_ -split '\s+', 2)[1] -eq $zip })
if ($entry.Count -ne 1) { throw "Expected one checksum entry for $zip" }
$expected = ($entry[0] -split '\s+', 2)[0]
if ((Get-FileHash $zip -Algorithm SHA256).Hash -ne $expected) {
throw "Checksum verification failed for $zip"
}
Write-Output "Checksum OK: $zip"
Continue only when the command prints Checksum OK for your ZIP:
Expand-Archive $zip -DestinationPath "$env:LOCALAPPDATA\Programs\aigw"
$env:Path = "$env:LOCALAPPDATA\Programs\aigw;$env:Path"
aigw version
Add the installation directory to your user Path for future terminals, then log in in PowerShell.
Troubleshooting
| Symptom | Action |
|---|---|
| Status shows the wrong API | Update the DevCLI to v0.2.0 or later and remove custom endpoint overrides; status should show https://api.aigw.loginid.ai |
HTTP 401 or exit code 3 | Check keySource with aigw status -o json. Update or remove AIGW_API_KEY if it overrides your saved login; otherwise run aigw login with an active Account API key |
| No usable credential store | Use AIGW_API_KEY, or aigw login --insecure-storage to save the key in a plaintext file; see Linux without a credential store |
Exit code 4 | Use a key with the permission named by the error; status requires project:read |
| Secret file already exists | Choose a new file path; the DevCLI does not overwrite a stored credential |
| A field is not accepted | Run the command with --help to find its flags and nested field names |
| JSON parsing fails | Check the exit code first and keep stderr separate from stdout |