PRE-RELEASE INFORMATION: SUBJECT TO CHANGE

housectl Command Reference

housectl is the command-line interface for the housecarl authorization system. It provides comprehensive tools for managing tenants, users, domains, policies, API keys, and performing authorization checks.

Installation

Build with Bazel:

./bzsh build //housecarl/src/bin:housectl

Or use the Makefile shortcut:

make cli

Binary location: ./bazel-bin/housecarl/src/bin/housectl

Quick Start

# 1. Login to a housecarl server
housectl config login https://housecarl.example.com admin --tenant system

# 2. Check your connection
housectl config ping

# 3. Explore available commands
housectl <COMMAND> --help

Global Options

These options are available for all commands:

OptionDescription
--context <NAME>Use a specific context for this command (overrides HOUSECARL_CONTEXT)
--config <FILE>Path to configuration file (overrides default location)
--log-level <LEVEL>Logging verbosity: 0=error, 1=warn, 2=info, 3=debug, 4=trace
-o, --format <FORMAT>Output format: pretty (default), table, or json
--interface-versionPrint interface version and exit (for scripting compatibility)
--helpDisplay help information
--versionDisplay version information

Environment Variables

VariableDescriptionPriority
HOUSECARL_ENDPOINTDirect endpoint override (requires HOUSECARL_TOKEN)Highest
HOUSECARL_TOKENDirect token override (requires HOUSECARL_ENDPOINT)Highest
HOUSECARL_CONTEXTContext name to use (overrides config default)Medium
HOUSECARL_CONFIG_PATHCustom config file path (must be absolute)N/A
HOUSECTL_PASSWORDPassword for login (avoids interactive prompt)N/A

Precedence Order (highest to lowest):

  1. HOUSECARL_ENDPOINT + HOUSECARL_TOKEN (direct connection, bypasses config)
  2. --context CLI flag
  3. HOUSECARL_CONTEXT environment variable
  4. current context from config file

Configuration

Configuration File Location

All Platforms: ~/.config/housecarl.toml

Configuration File Structure (Multi-Context TOML)

current = "admin@acme@localhost"

[contexts.admin@acme@localhost]
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
endpoint = "http://localhost:50051"
user_id = "7c9e6679-7425-40de-944b-e07fc1f90ae7"
username = "admin"
tenant_id = "550e8400-e29b-41d4-a716-446655440000"

[contexts.devuser@staging@staging-server]
token = "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9..."
endpoint = "https://staging.example.com:50051"
user_id = "8c9e6679-7425-40de-944b-e07fc1f90ae8"
username = "devuser"
tenant_id = "660e8400-e29b-41d4-a716-446655440001"

Configuration Fields:

  • current: Name of the currently active context
  • contexts: Map of context configurations by name
    • Context names are auto-generated in format username@tenant@host
    • token: JWT authentication token (obtained from login)
    • tenant_id: UUID of the tenant (optional for system tenant)
    • user_id: UUID of the authenticated user
    • endpoint: gRPC endpoint URL
    • username: Username for display purposes

Commands

config

Authentication and connection configuration commands.

config login

Authenticate with a housecarl server and establish a session.

Usage:

housectl config login <ENDPOINT> <USERNAME> [OPTIONS]

Arguments:

  • <ENDPOINT> - Server URL (gRPC endpoint, e.g., https://housecarl.example.com or http://localhost:50051)
  • <USERNAME> - Username for authentication

Options:

  • --tenant <TENANT> - Tenant ID or name to authenticate against
  • --password <PASSWORD> - Password (or set HOUSECTL_PASSWORD env var; will prompt if not provided)
  • --duration <SECONDS> - Session token validity in seconds (default: 43200 = 12 hours)
  • --as <CONTEXT_NAME> - Use custom context name instead of auto-generated one

Examples:

# Login with interactive password prompt
housectl config login https://housecarl.example.com admin --tenant system

# Login with password from environment variable
export HOUSECTL_PASSWORD=secret123
housectl config login http://localhost:50051 alice --tenant acme-corp

# Login with password flag
housectl config login http://localhost:50051 alice --tenant acme-corp --password secret123

# Login with custom token duration (24 hours)
housectl config login https://housecarl.example.com admin --tenant system --duration 86400

# Login with custom context name
housectl config login http://localhost:50051 admin --tenant acme --as my-local-dev

Notes:

  • On successful login, a signed JWT token is stored locally
  • Token is used for subsequent commands
  • Password can be provided via flag, environment variable, or interactive prompt

config logout

Clear stored credentials and end the current session.

Usage:

housectl config logout

Example:

housectl config logout

config status

Display current authentication status and configuration details.

Usage:

housectl config status

Example:

housectl config status

Output includes:

  • Configuration file path
  • Server URL
  • Tenant ID
  • User ID
  • Username
  • Token timestamps (exp, nbf, iat) in pretty format

config ping

Verify connection to the server with current credentials.

Usage:

housectl config ping

Example:

housectl config ping

Notes:

  • Use this to verify your session is still valid
  • Confirms the server is reachable

config health

Check server health status.

Usage:

housectl config health [OPTIONS]

Options:

  • --watch - Continuously monitor health status (stream updates until Ctrl+C)

Examples:

# Single health check
housectl config health

# Continuous health monitoring
housectl config health --watch

Health Status Codes:

  • 0 - UNKNOWN
  • 1 - SERVING
  • 2 - NOT_SERVING
  • 3 - SERVICE_UNKNOWN

config list

List all available contexts.

Usage:

housectl config list

Example:

housectl config list

Output:

CONTEXT NAME                    ENDPOINT                         CURRENT
admin@acme@localhost            http://localhost:50051           *
devuser@staging@staging-server  https://staging.example.com:50051

config current

Show the current active context name.

Usage:

housectl config current

Example:

housectl config current

Output:

admin@acme@localhost

config use

Switch to a different context.

Usage:

housectl config use <CONTEXT_NAME>

Arguments:

  • <CONTEXT_NAME> - Name of the context to switch to

Example:

housectl config use devuser@staging@staging-server

Notes:

  • Use housectl config list to see available contexts
  • The context must exist in the configuration file

config show

Show details of a specific context.

Usage:

housectl config show <CONTEXT_NAME>

Arguments:

  • <CONTEXT_NAME> - Name of the context to show details for

Example:

housectl config show admin@acme@localhost

Output:

Context: admin@acme@localhost
  Endpoint: http://localhost:50051
  Username: admin
  User ID:  7c9e6679-7425-40de-944b-e07fc1f90ae7
  Tenant:   550e8400-e29b-41d4-a716-446655440000

config remove

Remove a context from the configuration.

Usage:

housectl config remove <CONTEXT_NAME>

Arguments:

  • <CONTEXT_NAME> - Name of the context to remove

Example:

housectl config remove old-context

Notes:

  • Cannot remove the current active context
  • Use housectl config use to switch contexts first

user

User account management commands.

user create

Create a new user account.

Usage:

housectl user create <USERNAME> <PASSWORD> <EMAIL>

Arguments:

  • <USERNAME> - Unique username for the account
  • <PASSWORD> - Password (min 8 characters, must include uppercase, lowercase, number, and special character)
  • <EMAIL> - Email address for the account

Example:

housectl user create alice Secret123! alice@example.com

Password Requirements:

  • Minimum 8 characters
  • At least one uppercase letter
  • At least one lowercase letter
  • At least one number
  • At least one special character

user get

Retrieve user details by ID or username.

Usage:

housectl user get <USER>

Arguments:

  • <USER> - User ID (UUID format) or username

Examples:

# Get by username
housectl user get alice

# Get by UUID
housectl user get 550e8400-e29b-41d4-a716-446655440000

user update

Modify user account properties.

Usage:

housectl user update <USER> [OPTIONS]

Arguments:

  • <USER> - User ID (UUID format) or username

Options:

  • --username <USERNAME> - New username
  • --email <EMAIL> - New email address
  • --active <BOOL> - Set active status (true to enable, false to disable)

Example:

housectl user update alice --email newemail@example.com --active true

user change-password

Change a user's password.

Usage:

housectl user change-password <USER> <PASSWORD>

Arguments:

  • <USER> - User ID (UUID format) or username
  • <PASSWORD> - New password (must meet password requirements)

Example:

housectl user change-password alice NewSecret123!

user delete

Permanently delete a user account.

Usage:

housectl user delete <USER> [OPTIONS]

Arguments:

  • <USER> - User ID (UUID format) or username to delete

Options:

  • -y, --yes - Skip confirmation prompt (use with caution)

Example:

housectl user delete alice --yes

Warning: This action is irreversible.


tenant

Tenant management and user association commands.

tenant get

Retrieve tenant details by ID or name.

Usage:

housectl tenant get <ID>

Arguments:

  • <ID> - Tenant ID (UUID) or unique name

Examples:

# Get by name
housectl tenant get acme-corp

# Get by UUID
housectl tenant get 550e8400-e29b-41d4-a716-446655440000

tenant current

Display the tenant associated with your current login session.

Usage:

housectl tenant current

Example:

housectl tenant current

tenant update

Modify tenant properties.

Usage:

housectl tenant update <ID> [OPTIONS]

Arguments:

  • <ID> - Tenant ID (UUID) or name to update

Options:

  • --name <NAME> - New display name for the tenant
  • --description <DESCRIPTION> - New description for the tenant
  • --subscription <PLAN> - Subscription plan identifier (e.g., 'free', 'pro', 'enterprise')
  • --active <BOOL> - Set active status (true to enable, false to disable)

Example:

housectl tenant update acme-corp --name "Acme Corporation" --description "Updated description"

tenant delete

Permanently delete a tenant and all associated resources.

Usage:

housectl tenant delete <ID> [OPTIONS]

Arguments:

  • <ID> - Tenant ID (UUID) or name to delete

Options:

  • -y, --yes - Skip confirmation prompt (use with extreme caution)

Example:

housectl tenant delete acme-corp --yes

Warning: This action is irreversible and will delete all domains, policies, and user associations.

tenant disable-domain

Disable a specific domain within a tenant.

Usage:

housectl tenant disable-domain <DOMAIN> [OPTIONS]

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name to disable

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)

Example:

housectl tenant disable-domain billing-domain --tenant acme-corp

tenant associate-user

Grant a user access to a tenant.

Usage:

housectl tenant associate-user <TENANT> <USERNAME>

Arguments:

  • <TENANT> - Tenant ID (UUID) or name to associate the user with
  • <USERNAME> - Username to associate

Examples:

# Associate by tenant name
housectl tenant associate-user acme-corp alice@example.com

# Associate by tenant UUID
housectl tenant associate-user 550e8400-e29b-41d4-a716-446655440000 alice@example.com

tenant disassociate-user

Remove a user's access from a tenant.

Usage:

housectl tenant disassociate-user <TENANT> <USERNAME>

Arguments:

  • <TENANT> - Tenant ID (UUID) or name to remove the user from
  • <USERNAME> - Username to remove

Examples:

housectl tenant disassociate-user acme-corp alice@example.com
housectl tenant disassociate-user 550e8400-e29b-41d4-a716-446655440000 alice@example.com

tenant is-user-associated

Check if a user is associated with a tenant.

Usage:

housectl tenant is-user-associated <TENANT> <USERNAME>

Arguments:

  • <TENANT> - Tenant ID (UUID) or name to check
  • <USERNAME> - Username to check

Examples:

housectl tenant is-user-associated acme-corp alice@example.com
housectl tenant is-user-associated 550e8400-e29b-41d4-a716-446655440000 alice@example.com

tenant all-associated-users

List all users associated with a tenant.

Usage:

housectl tenant all-associated-users [TENANT]

Arguments:

  • [TENANT] - Tenant ID (UUID) or name (defaults to your current tenant)

Examples:

# List users in current tenant
housectl tenant all-associated-users

# List users in specific tenant by name
housectl tenant all-associated-users acme-corp

# List users in specific tenant by UUID
housectl tenant all-associated-users 550e8400-e29b-41d4-a716-446655440000

tenant service-account create

Create a service account for automated systems and integrations.

Usage:

housectl tenant service-account create <NAME> <DESCRIPTION> [OPTIONS]

Arguments:

  • <NAME> - Service account name (will be automatically prefixed with 'svc:')
  • <DESCRIPTION> - Human-readable description of the service account's purpose

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)
  • --expiration-days <DAYS> - API key expiration period in days (default: 365)

Example:

housectl tenant service-account create billing-webhook "Handles billing webhooks" --expiration-days 90

tenant service-account list

List all service accounts for a tenant.

Usage:

housectl tenant service-account list [OPTIONS]

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)
  • --active-only - Filter to show only active service accounts

Example:

housectl tenant service-account list --active-only

tenant service-account get

Retrieve details of a specific service account.

Usage:

housectl tenant service-account get <ID>

Arguments:

  • <ID> - Service account ID (UUID format)

Example:

housectl tenant service-account get 550e8400-e29b-41d4-a716-446655440000

tenant service-account update

Update a service account's status.

Usage:

housectl tenant service-account update <ID> [OPTIONS]

Arguments:

  • <ID> - Service account ID (UUID format)

Options:

  • --active <BOOL> - Set active status (true to enable, false to disable)

Example:

housectl tenant service-account update 550e8400-e29b-41d4-a716-446655440000 --active false

tenant service-account delete

Permanently delete a service account and revoke its access.

Usage:

housectl tenant service-account delete <ID> [OPTIONS]

Arguments:

  • <ID> - Service account ID (UUID format)

Options:

  • -y, --yes - Skip confirmation prompt (use with caution)

Example:

housectl tenant service-account delete 550e8400-e29b-41d4-a716-446655440000 --yes

Warning: This action is irreversible and will revoke all access for this service account.


admin

System administration commands (requires admin privileges).

admin create

Create a new tenant organization.

Usage:

housectl admin create <NAME> <DESCRIPTION>

Arguments:

  • <NAME> - Unique name for the tenant organization (≤100 characters)
  • <DESCRIPTION> - Human-readable description of the tenant (≤500 characters)

Example:

housectl admin create "Acme Corp" "Enterprise customer"

Input Validation:

  • Tenant name: ≤100 characters, cannot be empty
  • Description: ≤500 characters, cannot be empty

admin disable

Disable a tenant (suspends all access for that organization).

Usage:

housectl admin disable [TENANT_ID] [OPTIONS]

Arguments:

  • [TENANT_ID] - Tenant ID (UUID) to disable; defaults to current tenant if omitted

Options:

  • -y, --yes - Skip confirmation prompt

Example:

housectl admin disable 550e8400-e29b-41d4-a716-446655440000

admin enable

Enable a previously disabled tenant.

Usage:

housectl admin enable [TENANT_ID] [OPTIONS]

Arguments:

  • [TENANT_ID] - Tenant ID (UUID) to enable; defaults to current tenant if omitted

Options:

  • -y, --yes - Skip confirmation prompt

Example:

housectl admin enable 550e8400-e29b-41d4-a716-446655440000

admin tenant-set-enabled

Set tenant enabled/disabled status explicitly.

Usage:

housectl admin tenant-set-enabled <STATUS> [TENANT_ID] [OPTIONS]

Arguments:

  • <STATUS> - Target status: true (enabled) or false (disabled)
  • [TENANT_ID] - Tenant ID (UUID); defaults to current tenant if omitted

Options:

  • -y, --yes - Skip confirmation prompt

Example:

housectl admin tenant-set-enabled true 550e8400-e29b-41d4-a716-446655440000

admin list

List all tenants in the system.

Usage:

housectl admin list

Example:

housectl admin list

admin list-users

List all users across all tenants.

Usage:

housectl admin list-users

Example:

housectl admin list-users

admin refresh-tenants

Reset API call limit counters for all tenants.

Usage:

housectl admin refresh-tenants

Example:

housectl admin refresh-tenants

Notes:

  • Use this after changing call limit configurations
  • Clears accumulated usage counters (resets call quotas to maximum)

domain

Domain management commands (authorization policy containers).

domain create

Create a new authorization domain with policies.

Usage:

housectl domain create <NAME> [TENANT] [POLICIES...]

Arguments:

  • <NAME> - Unique name for the domain
  • [TENANT] - Tenant ID or name (defaults to your current tenant)
  • [POLICIES...] - Policy files or directories to include in the domain

Examples:

# Create domain with single policy file
housectl domain create billing-domain ./policies/billing.hcl

# Create domain with policy directory
housectl domain create api-access my-tenant ./policies/

# Create domain with multiple policy files
housectl domain create production-access acme-corp policy1.hcl policy2.hcl

Notes:

  • Domains are containers for authorization policies
  • Define access control rules for resources

domain get

Retrieve domain details by ID or name.

Usage:

housectl domain get <DOMAIN> [OPTIONS]

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)

Examples:

# Get by name
housectl domain get billing-domain

# Get by UUID with specific tenant
housectl domain get 550e8400-e29b-41d4-a716-446655440000 --tenant acme-corp

domain list

List all domains in a tenant.

Usage:

housectl domain list [OPTIONS]

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)

Examples:

# List domains in current tenant
housectl domain list

# List domains in specific tenant
housectl domain list --tenant acme-corp

domain update

Modify domain properties.

Usage:

housectl domain update <DOMAIN> [OPTIONS]

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name to update

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)
  • --name <NAME> - New name for the domain
  • --active <BOOL> - Set active status (true to enable, false to disable)

Example:

housectl domain update billing-domain --name new-billing-domain --active true

domain delete

Permanently delete a domain and its policies.

Usage:

housectl domain delete <DOMAIN> [OPTIONS]

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name to delete

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)
  • -y, --yes - Skip confirmation prompt (use with caution)

Example:

housectl domain delete billing-domain --yes

Warning: This action is irreversible.

domain put-policies

Replace all policies in a domain.

Usage:

housectl domain put-policies <DOMAIN> <POLICIES...>

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name to update
  • <POLICIES...> - Policy files or directories to deploy

Examples:

# Replace with policy directory
housectl domain put-policies billing-domain ./policies/

# Replace with specific policy files
housectl domain put-policies api-domain policy1.hcl policy2.hcl

Notes:

  • This is an atomic operation
  • Either all policies are updated or none are

domain list-policies

List all policies in a domain.

Usage:

housectl domain list-policies <DOMAIN> [OPTIONS]

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)

Examples:

# List policies by domain name
housectl domain list-policies billing-domain

# List policies by domain UUID
housectl domain list-policies 550e8400-e29b-41d4-a716-446655440000

domain get-policy

Get a specific policy from a domain by name.

Usage:

housectl domain get-policy <DOMAIN> <POLICY_NAME> [OPTIONS]

Arguments:

  • <DOMAIN> - Domain ID (UUID) or name
  • <POLICY_NAME> - Policy name to retrieve

Options:

  • --tenant <TENANT> - Tenant ID or name (defaults to your current tenant)

Examples:

housectl domain get-policy billing-domain admin-access
housectl domain get-policy api-domain read-only-policy

authz

Authorization checks and policy management commands.

authz can-i

Check if a request is authorized against server policies.

Usage:

housectl authz can-i <REQUEST_FILE>

Arguments:

  • <REQUEST_FILE> - Path to JSON file containing the authorization request

Example:

housectl authz can-i request.json

Request File Format (request.json):

{
  "subject": "user:alice",
  "action": "read",
  "object": {
    "type": "document",
    "id": "doc-123"
  }
}

Response:

  • Returns ALLOW or DENY with the matching policy (if any)
  • Includes policy evaluation details

authz can-i-maybe

Test authorization with custom policies (speculative check).

Usage:

housectl authz can-i-maybe <REQUEST> <POLICIES...>

Arguments:

  • <REQUEST> - Request to check (use 'file://' prefix for file path, or inline JSON)
  • <POLICIES...> - Policy files or directories to evaluate against (in addition to server policies)

Examples:

# Test with policy directory
housectl authz can-i-maybe request.json ./policies/

# Test with file URI
housectl authz can-i-maybe file://request.json policy1.hcl policy2.hcl

Notes:

  • Evaluates request using both server policies and locally-provided test policies
  • Useful for testing policy changes before deployment

authz can-i-local

Evaluate authorization locally without server connection.

Usage:

housectl authz can-i-local --request <FILE> [OPTIONS] <POLICIES...>

Arguments:

  • <POLICIES...> - Policy files or directories to evaluate against

Options:

  • --request <FILE> - Path to JSON file containing the authorization request
  • --tenant <UUID> - Tenant ID to simulate (equivalent to JWT tenant_id claim)
  • --domain <DOMAIN> - Domain name or ID to evaluate against

Examples:

# Local evaluation with policy directory
housectl authz can-i-local --request request.json ./policies/

# Local evaluation with tenant context
housectl authz can-i-local --request request.json --tenant 550e8400-e29b-41d4-a716-446655440000 ./policies/

Notes:

  • Performs authorization evaluation entirely offline
  • Useful for testing and development without a running server

authz parse-policies

Parse and validate policy files without executing them.

Usage:

housectl authz parse-policies <POLICIES...>

Arguments:

  • <POLICIES...> - Policy files or directories to validate

Examples:

# Validate policy directory
housectl authz parse-policies ./policies/

# Validate specific policy files
housectl authz parse-policies policy1.hcl policy2.hcl

Exit Codes:

  • 0 - All policies are valid
  • 1 - One or more policies have errors

Notes:

  • Validates policy syntax and structure
  • Useful for CI/CD pipelines and pre-commit hooks

api-key

API key management for programmatic access.

api-key create

Create a new API key for programmatic access.

Usage:

housectl api-key create <USER_ID>

Arguments:

  • <USER_ID> - User ID (UUID format) to create key for

Example:

housectl api-key create 550e8400-e29b-41d4-a716-446655440000

api-key get

Retrieve details of an existing API key.

Usage:

housectl api-key get <USER_ID> <KEY_ID>

Arguments:

  • <USER_ID> - User ID (UUID format) who owns the key
  • <KEY_ID> - API key ID (UUID format) to retrieve

Example:

housectl api-key get 550e8400-e29b-41d4-a716-446655440000 660e8400-e29b-41d4-a716-446655440001

api-key delete

Delete an API key (revokes programmatic access).

Usage:

housectl api-key delete <USER_ID> <KEY_ID> [OPTIONS]

Arguments:

  • <USER_ID> - User ID (UUID format) who owns the key
  • <KEY_ID> - API key ID (UUID format) to delete

Options:

  • -y, --yes - Skip confirmation prompt (use with caution)

Example:

housectl api-key delete 550e8400-e29b-41d4-a716-446655440000 660e8400-e29b-41d4-a716-446655440001 --yes

Error Handling

Exit Codes

CodeMeaning
0Success or operation cancelled
1Generic error
2Invalid input
3Not authenticated
4API error
5Client error
6IO error
7Invalid state

Common Errors

Not Logged In:

Error: NotLoggedInError
Please run: housectl config login

Solution: Run housectl config login <ENDPOINT> <USERNAME> --tenant <TENANT>

Token Expired:

Error: Your token will expire in less than 5 minutes

Solution: housectl automatically attempts to refresh tokens. If this fails, re-login.

Connection Error:

Error: Cannot connect to the server

Solutions:

  • Check that the server is running
  • Verify the endpoint URL is correct
  • Check your network connection

Invalid Configuration:

Error: ConfigurationError

Solution: Check configuration file exists and has correct permissions (chmod 600)


Output Formats

Pretty Format (Default)

Human-readable output with formatting:

housectl user get alice
User: alice
ID: 550e8400-e29b-41d4-a716-446655440000
Email: alice@example.com
Active: true

JSON Format

Machine-parsable output:

housectl user get alice --format json
{
  "username": "alice",
  "id": "550e8400-e29b-41d4-a716-446655440000",
  "email": "alice@example.com",
  "active": true
}

Table Format

Tabular output for list commands:

housectl admin list --format table
ID                                   NAME        ACTIVE
550e8400-e29b-41d4-a716-446655440000 acme-corp   true
660e8400-e29b-41d4-a716-446655440001 beta-corp   true

Scripting and Automation

Using JSON Output for Parsing

#!/bin/bash
# Extract user emails
housectl admin list-users --format json | jq -r '.users[].email'

Using Environment Variables

#!/bin/bash
# Automated login
export HOUSECTL_PASSWORD=secret123
housectl config login https://housecarl.example.com admin --tenant system

Batch Operations

#!/bin/bash
# Create multiple users from CSV

while IFS=, read -r username email password; do
  housectl user create "$username" "$password" "$email"
done < users.csv

Error Handling in Scripts

#!/bin/bash
# Check exit codes

if housectl config ping; then
  echo "Server is reachable"
else
  echo "Server is unreachable (exit code: $?)"
  exit 1
fi

Best Practices

Security

  • Protect configuration files: chmod 600 ~/.config/housecarl.toml
  • Use strong passwords (min 8 chars, mixed case, numbers, special chars)
  • Rotate API keys regularly
  • Don't commit config files to version control
  • Use environment-specific credentials
  • Set appropriate token durations for your use case

Operations

  • Test authorization changes in non-production first
  • Backup policies before making changes
  • Use descriptive names for tenants and domains
  • Document policy decisions
  • Review audit logs regularly
  • Use --yes flag only in automated scripts

Development

  • Use separate tenants for dev/staging/prod
  • Script repetitive operations
  • Validate inputs before submission
  • Handle errors gracefully in scripts
  • Use authz parse-policies in CI/CD pipelines
  • Test policies locally before deployment with authz can-i-local

Advanced Usage

Multi-Environment Management

# Login to different environments (each creates a context)
housectl config login https://dev.housecarl.example.com admin --tenant system
housectl config login https://prod.housecarl.example.com admin --tenant system

# List all available contexts
housectl config list

# Switch between environments
housectl config use admin@system@dev.housecarl.example.com
housectl config use admin@system@prod.housecarl.example.com

# Use environment variable for scripts
HOUSECARL_CONTEXT=admin@system@prod.housecarl.example.com housectl user list-users

# Use --context flag for one-off commands
housectl --context admin@system@prod.housecarl.example.com user list-users

Policy Testing Workflow

# 1. Parse policies locally
housectl authz parse-policies ./policies/

# 2. Test locally without server
housectl authz can-i-local --request test-request.json ./policies/

# 3. Test speculatively with server
housectl authz can-i-maybe test-request.json ./policies/

# 4. Deploy to server
housectl domain put-policies production ./policies/

# 5. Verify with real authorization check
housectl authz can-i test-request.json

Continuous Integration

# Example GitHub Actions workflow
- name: Validate Policies
  run: |
    ./housectl authz parse-policies ./policies/
    if [ $? -ne 0 ]; then
      echo "Policy validation failed"
      exit 1
    fi

Troubleshooting

Cannot Connect to Server

# Check server is running
curl http://localhost:50051

# Verify configuration
housectl config status

# Test connection
housectl config ping

Token Issues

# Check token status
housectl config status

# Re-login to get new token
housectl config login <ENDPOINT> <USERNAME> --tenant <TENANT>

Permission Denied

Ensure the authenticated user has appropriate permissions:

  • Admin operations require admin role
  • Tenant operations require tenant membership
  • Some operations are tenant-scoped

Config File Errors

# Check file exists
ls -la ~/.config/housecarl.toml

# Check permissions
chmod 600 ~/.config/housecarl.toml

# List available contexts
housectl config list

# Recreate config with login
rm ~/.config/housecarl.toml
housectl config login <ENDPOINT> <USERNAME> --tenant <TENANT>

Context Not Found

If you get a "Context not found" error:

# List available contexts
housectl config list

# Switch to an existing context
housectl config use <context-name>

# Or login again to create a new context
housectl config login <ENDPOINT> <USERNAME> --tenant <TENANT>


Support

For issues, bug reports, or feature requests, visit:

  • GitHub Issues: https://github.com/upside-down-research/code/issues
  • Documentation: https://housecarl.cloud/docs