Grant CLI
The Grant CLI (@grantjs/cli) is the fastest way to connect your project to a Grant instance. It walks you through authentication, account/project selection, and stores everything in a local config file — ready for type generation and SDK usage.
Installation
pnpm add -g @grantjs/cli
# or
npm install -g @grantjs/cliCommands
| Command | Description |
|---|---|
grant start | Interactive setup wizard (API URL, auth, scope) |
grant generate-types | Generate TypeScript types from your project's resources |
grant config list | List all profiles |
grant config show | Show current profile details |
grant config set ... | Update profile settings |
grant version | Show CLI version |
All commands support -p, --profile <name> to target a specific profile.
Interactive Setup: grant start
The start command walks you through connecting to a Grant instance. There are two authentication paths — Session (browser login) and API key (machine-to-machine).
Session Authentication (Email)
$ grant start
? Profile name: default
? Grant API base URL: http://localhost:4000
? Authentication method: Session (log in via browser)
? Sign-in method: Email
? Email: admin@example.com
? Password: ********
? Select account or organization:
❯ Personal account
Acme Corp
Startup Inc
? Select project:
Internal Tools (internal-tools)
❯ My App (my-app)
Staging (staging)
? Default output path for generate-types (optional, leave empty for ./grant-types.ts):
./src/grant-types.ts
Setup complete. Config saved to: /home/user/.config/grant/config.json
Profile: default
API URL: http://localhost:4000
Auth: Session
Scope tenant: organizationProject
Scope id: 8a3b...c1d2:f4e5...a6b7
Generate-types output: ./src/grant-types.tsSession Authentication (GitHub)
$ grant start
? Profile name: default
? Grant API base URL: http://localhost:4000
? Authentication method: Session (log in via browser)
? Sign-in method: GitHub
Opening browser for GitHub sign-in…The CLI opens your browser to complete GitHub OAuth. After sign-in, the browser shows "Successfully signed in with GitHub. You can close this tab and return to the terminal." and the CLI continues with account/project selection.
API Key Authentication
Use this path for CI/CD pipelines, scripts, or any non-interactive environment.
Project-Level API Keys Required
The CLI requires a project-level API key — scoped to accountProject or organizationProject. These keys represent a service identity tied to a role, not a specific user.
This is different from a user API key (scoped to accountProjectUser or organizationProjectUser), which is tied to an individual user's permissions within a project. User API keys are created for personal access and inherit the user's roles; project-level keys are created for automation and carry their own role directly.
To create a project-level API key, see Step 8 of the Integration Guide or use the Grant web dashboard under Project > API Keys.
$ grant start
? Profile name: ci
? Grant API base URL: https://grant.example.com
? Authentication method: API key (clientId + secret)
? API key client ID (UUID): 3f2a1b4c-5d6e-7f8a-9b0c-1d2e3f4a5b6c
? API key client secret: ********************************
? Scope tenant:
❯ Organization project (organizationId:projectId)
Account project (accountId:projectId)
? Scope ID (e.g. organizationId:projectId): 8a3bc1d2-...:f4e5a6b7-...
? Default output path for generate-types (optional, leave empty for ./grant-types.ts):
Setup complete. Config saved to: /home/user/.config/grant/config.json
Profile: ci
API URL: https://grant.example.com
Auth: API key
Scope tenant: organizationProject
Scope id: 8a3bc1d2-...:f4e5a6b7-...
Generate-types output: ./grant-types.tsProfiles
Multi-Environment Workflow
Profiles let you store separate configurations for each environment — local development, staging, production, CI — in a single config file. Switch between them with -p:
grant generate-types # uses default profile
grant generate-types -p staging # uses staging profile
grant generate-types -p ci # uses CI profileRun grant start multiple times with different profile names to set up each environment:
grant start # creates/updates "default" profile
grant start -p staging # creates/updates "staging" profile
grant start -p production # creates/updates "production" profileManaging Profiles
$ grant config list
Config path: /home/user/.config/grant/config.json
Exists: true
Default profile: default
- default (default)
- staging
- production
- ci$ grant config show
Config path: /home/user/.config/grant/config.json
Exists: true
Profile: default
API URL: http://localhost:4000
Auth method: session
Selected scope: organizationProject:8a3bc1d2-...:f4e5a6b7-...
Generate-types output: ./src/grant-types.ts$ grant config show -p ci
Config path: /home/user/.config/grant/config.json
Exists: true
Profile: ci
API URL: https://grant.example.com
Auth method: api-key
Selected scope: organizationProject:8a3bc1d2-...:f4e5a6b7-...
Generate-types output: ./grant-types.tsUpdating Settings
# Change the default profile
grant config set default-profile staging
# Update API URL for a profile
grant config set api-url https://new-api.example.com -p staging
# Update API key credentials
grant config set credentials \
--client-id 3f2a1b4c-... \
--client-secret "..." \
--scope-tenant organizationProject \
--scope-id "orgId:projectId" \
-p ci
# Update selected scope
grant config set scope \
--tenant organizationProject \
--scope-id "orgId:projectId" \
-p staging
# Update generate-types output path
grant config set generate-types-output ./src/types/grant.ts -p defaultConfig File Structure
The config file is stored at ~/.config/grant/config.json (Linux/macOS) or %APPDATA%\grant\config.json (Windows) with 0600 permissions (owner read/write only).
Secrets Handling
Session tokens and API key secrets are stored in the config file. The file is created with restrictive permissions (0600). For CI/CD, prefer environment variables or secret managers over storing credentials on disk.
{
"defaultProfile": "default",
"profiles": {
"default": {
"apiUrl": "http://localhost:4000",
"authMethod": "session",
"session": {
"token": "eyJhbG...",
"refreshToken": "eyJhbG..."
},
"selectedScope": {
"tenant": "organizationProject",
"id": "8a3bc1d2-...:f4e5a6b7-..."
},
"generateTypesOutputPath": "./src/grant-types.ts"
},
"ci": {
"apiUrl": "https://grant.example.com",
"authMethod": "api-key",
"apiKey": {
"clientId": "3f2a1b4c-5d6e-7f8a-9b0c-1d2e3f4a5b6c",
"clientSecret": "...",
"scope": {
"tenant": "organizationProject",
"id": "8a3bc1d2-...:f4e5a6b7-..."
}
},
"selectedScope": {
"tenant": "organizationProject",
"id": "8a3bc1d2-...:f4e5a6b7-..."
}
}
}
}Generate Types: grant generate-types
Generates a TypeScript file with ResourceSlug and ResourceAction constants derived from your project's resources and permissions. Use these with @grantjs/server guards for compile-time safety.
$ grant generate-types
✔ Resolved access token
✔ Fetched 3 resources and 12 permissions
✔ Written to ./src/grant-types.tsThe generated file looks like:
// Auto-generated by @grantjs/cli — do not edit manually
export const ResourceSlug = {
Document: 'document',
User: 'user',
Report: 'report',
} as const;
export type ResourceSlug = (typeof ResourceSlug)[keyof typeof ResourceSlug];
export const ResourceAction = {
Create: 'Create',
Read: 'Read',
Update: 'Update',
Delete: 'Delete',
Query: 'Query',
} as const;
export type ResourceAction = (typeof ResourceAction)[keyof typeof ResourceAction];Options
| Flag | Description |
|---|---|
-o, --output <path> | Override the output file path |
--dry-run | Print generated types to stdout without writing |
-p, --profile <name> | Use a specific profile |
# Override output path
grant generate-types -o ./types/grant.ts
# Preview without writing
grant generate-types --dry-run
# Generate from staging profile
grant generate-types -p stagingType-Safe Guards
After generating types, use them in your @grantjs/server guards to catch typos at compile time:
import { ResourceSlug, ResourceAction } from './grant-types';
import { grant } from '@grantjs/server/express';
app.get(
'/documents',
grant(grantClient, {
resource: ResourceSlug.Document,
action: ResourceAction.Query,
}),
(req, res) => res.json({ data: [] })
);Related:
- Integration Guide — End-to-end tutorial from resource creation to guarded endpoints
- Server SDK — Express, Fastify, NestJS, Next.js middleware
- API Keys — Token exchange and scoping details