@padua/cli
v2.5.0
Published
Unified AWS infrastructure management CLI
Readme
Padua CLI
A unified CLI for AWS infrastructure management—authentication, tunneling, and container tools in one place.
Installation
npm install -g @padua/cliPrerequisites
Required:
- Node.js v20+
- AWS CLI v2
Optional:
- npm (for CodeArtifact registry authentication)
- Docker (for ECR registry authentication)
- Session Manager Plugin (for
padua tunnelcommand)
Note:
padua initvalidates prerequisites and displays install URLs for any missing tools.
Quick Start
⚠️ WARNING:
padua initwill delete your existing~/.aws/configfile to ensure a clean configuration. A timestamped backup is automatically created at~/.aws/config.backup.<timestamp>. Use the--keep-existingflag to preserve custom non-Padua profiles.
# 1. Initialize configuration (discovers SSO accounts automatically)
padua init
# 2. Login to all services
padua loginThe init command will:
- Check for required prerequisites
- Detect AWS environment variables and warn if present
- Authenticate with AWS SSO
- Discover all accounts and roles you have access to
- Create a timestamped backup of
~/.aws/config - Delete and regenerate
~/.aws/configwith discovered profiles - Generate
~/.padua/padua.config.json
Features
| Category | Feature | Description |
|----------|---------|-------------|
| Auth | SSO Login | AWS SSO authentication and session management |
| | Profiles | Interactive AWS profile selection with shell integration |
| | CodeArtifact | Automatic npm registry authentication |
| | ECR | Docker registry authentication |
| Config | Init | Automatic SSO discovery and profile generation with backup |
| | Status | Health check for all authentication services |
| | Doctor | Configuration validation and diagnostics with fuzzy profile matching |
| Tunnel | RDS | Secure tunnels to RDS/Aurora databases via SSM |
| | LB | Port forwarding to internal ALB via SSM |
| | OpenSearch | Port forwarding to OpenSearch/Elasticsearch domains via SSM |
| Bedrock | Enable | Configure Claude Code to use AWS Bedrock inference (paduafg-production, ap-southeast-2) |
| | Disable | Restore previous Claude config from Bedrock mode |
| | Status | Report current Bedrock env state |
| | Setup | Install pbedrock shell function (bash/zsh/PowerShell) |
| Exec | ECS | Interactive shell in running ECS containers via SSM |
| MCP | Server | Built-in MCP server with 51 tools — GitLab, Atlassian, and code execution |
| | Daemon | Background process management via padua login |
| | Diagnostics | MCP health checks via padua doctor |
| | Migration | Token migration from legacy Go server |
MCP Server
@padua/cli v2 includes a built-in MCP (Model Context Protocol) server that exposes 51 tools and 6 resource templates for GitLab, Atlassian, and code execution. Any MCP-compatible client — Claude Code, Claude Desktop, Cursor, Windsurf, VS Code, etc. — can call these tools directly.
Setup
padua login # authenticates everything and starts the daemon
padua doctor # verify the server is healthypadua login runs a 7-step flow:
| Step | What happens |
|------|--------------|
| 1. AWS SSO | Authenticate to AWS |
| 2. S3 Config | Download MCP provider configuration to ~/.padua/mcp-providers.json |
| 3. CodeArtifact | Configure npm registry |
| 4. ECR | Configure Docker registry |
| 5. GitLab | OAuth2 PKCE authentication |
| 6. Atlassian | OAuth2 confidential client authentication |
| 7. MCP Daemon | Start background HTTP server on port 8919 |
Steps 5-7 are non-blocking — if a provider fails, the rest of Padua still works.
Architecture
┌─────────────────┐ HTTP POST ┌──────────────────────┐
│ Claude Code / │ ──────────────→ │ Padua MCP Daemon │
│ Claude Desktop │ Bearer token │ 127.0.0.1:8919/mcp │
│ Cursor / etc. │ ←────────────── │ │
└─────────────────┘ JSON-RPC │ ┌────────────────┐ │
│ │ GitLab (OAuth) │ │
│ │ 30 tools │ │
│ └────────────────┘ │
│ ┌────────────────┐ │
│ │ Atlassian (OAuth│) │
│ │ 19 tools │ │
│ └────────────────┘ │
└──────────────────────┘- Transport: HTTP with Streamable HTTP transport at
POST /mcp - Auth:
Authorization: Bearer padua-mcp-local(fixed token — the server only binds to localhost) - Tokens: OAuth tokens persisted to
~/.padua/tokens.db(AES-256-GCM encrypted), proactively refreshed before expiry and lazily refreshed on tool calls - Sessions: Multi-session support — multiple Claude Code instances share the daemon concurrently, each with an independent session. Stale sessions are swept after 30 minutes, max 10 concurrent sessions with LRU eviction
- Response format: All tools default to TOON (Token-Oriented Object Notation) for 40-60% token savings on list/search responses. Pass
"format": "json"on any tool call to receive raw JSON instead - Code mode:
call_tool_chainexecutes JavaScript in a secure V8 sandbox with all MCP tools available as synchronous namespaced functions (gitlab.*,jira.*,confluence.*).search_toolsprovides keyword search over all registered tools. The server sendsinstructionsduring initialization that guide LLM clients to prefercall_tool_chainfor multi-step operations automatically
IDE Configuration
Claude Code (~/.claude/settings.json)
Claude Code discovers MCP servers from its settings file. Add the padua server:
{
"mcpServers": {
"padua": {
"type": "url",
"url": "http://127.0.0.1:8919/mcp",
"headers": {
"Authorization": "Bearer padua-mcp-local"
}
}
}
}After adding the config, restart Claude Code or run /mcp to verify the server is connected.
Claude Desktop (~/Library/Application Support/Claude/claude_desktop_config.json)
{
"mcpServers": {
"padua": {
"url": "http://127.0.0.1:8919/mcp",
"headers": {
"Authorization": "Bearer padua-mcp-local"
}
}
}
}Cursor (.cursor/mcp.json)
{
"mcpServers": {
"padua": {
"url": "http://127.0.0.1:8919/mcp",
"headers": {
"Authorization": "Bearer padua-mcp-local"
}
}
}
}Windsurf (~/.windsurf/mcp.json)
{
"mcpServers": {
"padua": {
"serverUrl": "http://127.0.0.1:8919/mcp",
"headers": {
"Authorization": "Bearer padua-mcp-local"
}
}
}
}Any MCP Client (manual HTTP)
curl -X POST http://127.0.0.1:8919/mcp \
-H "Authorization: Bearer padua-mcp-local" \
-H "Content-Type: application/json" \
-d '{"jsonrpc":"2.0","id":1,"method":"tools/list"}'Tool Reference
GitLab — Repository (10 tools)
| Tool | Description |
|------|-------------|
| gitlab_list_projects | List projects accessible to the authenticated user |
| gitlab_get_project | Get project metadata by ID |
| gitlab_get_file | Get file content from a repository |
| gitlab_create_file | Create a new file in a repository |
| gitlab_update_file | Update an existing file in a repository |
| gitlab_list_branches | List branches in a project |
| gitlab_get_branch | Get a single branch by name |
| gitlab_search_code | Search for code across projects |
| gitlab_get_repository_tree | List files and directories in a repository tree |
| gitlab_get_clone_urls | Get clone URLs (SSH and HTTPS) for a project |
GitLab — Issues (4 tools)
| Tool | Description |
|------|-------------|
| gitlab_list_issues | List issues with filtering (project, state, labels, assignee) |
| gitlab_get_issue | Get a single issue by IID |
| gitlab_create_issue | Create a new issue |
| gitlab_update_issue | Update an existing issue (title, description, labels, state) |
GitLab — Merge Requests (11 tools)
| Tool | Description |
|------|-------------|
| gitlab_list_merge_requests | List merge requests with filtering |
| gitlab_get_merge_request | Get a single merge request by IID |
| gitlab_create_merge_request | Create a new merge request |
| gitlab_update_merge_request | Update MR title, description, labels, assignees |
| gitlab_get_merge_request_diffs | Get the diff/changes in a merge request |
| gitlab_list_merge_request_notes | List comments on a merge request |
| gitlab_create_merge_request_note | Add a comment to a merge request |
| gitlab_get_merge_request_approvals | Get approval status and required approvers |
| gitlab_approve_merge_request | Approve a merge request |
| gitlab_merge_merge_request | Merge a merge request |
| gitlab_rebase_merge_request | Rebase a merge request onto its target branch |
GitLab — Pipelines (5 tools)
| Tool | Description |
|------|-------------|
| gitlab_list_pipelines | List CI/CD pipelines for a project |
| gitlab_get_pipeline | Get pipeline details (status, duration, stages) |
| gitlab_list_pipeline_jobs | List jobs within a pipeline |
| gitlab_get_job_log | Get the log output of a CI/CD job |
| gitlab_retry_pipeline | Retry a failed pipeline |
Atlassian — Jira (11 tools)
| Tool | Description |
|------|-------------|
| atlassian_jira_search | Search issues using JQL |
| atlassian_jira_get_issue | Get a single issue by key (e.g., PROJ-123) |
| atlassian_jira_create_issue | Create a new issue (Bug, Story, Task, Epic, etc.) |
| atlassian_jira_update_issue | Update issue fields (summary, description, labels, etc.) |
| atlassian_jira_link_issues | Create a link between two issues (Blocks, Relates, etc.) |
| atlassian_jira_add_comment | Add a comment to an issue (supports Markdown) |
| atlassian_jira_transition_issue | Move an issue to a new status |
| atlassian_jira_list_projects | List accessible Jira projects |
| atlassian_jira_add_worklog | Log time spent on an issue |
| atlassian_jira_get_transitions | Get available transitions for an issue |
| atlassian_jira_get_issue_types | Get available issue types for a project |
Atlassian — Confluence (8 tools)
| Tool | Description |
|------|-------------|
| atlassian_confluence_search | Search Confluence using CQL |
| atlassian_confluence_get_page | Get page content by ID |
| atlassian_confluence_create_page | Create a new page in a space |
| atlassian_confluence_update_page | Update an existing page |
| atlassian_confluence_delete_page | Delete a page |
| atlassian_confluence_list_spaces | List accessible Confluence spaces |
| atlassian_confluence_get_space | Get space details by key |
| atlassian_confluence_search_content | Search page content |
Code Mode (2 tools)
| Tool | Description |
|------|-------------|
| call_tool_chain | Preferred for multi-step operations. Execute JavaScript in a secure isolated-vm V8 sandbox with all MCP tools available as synchronous namespaced functions (gitlab.*, jira.*, confluence.*). Supports configurable timeout and memory limit. Use __interfaces or __getToolInterface(name) for tool schema introspection |
| search_tools | Search registered MCP tools by keyword — matches against name and description, returns full schema information |
Resource Templates
Resources provide direct read access to specific entities by URI:
| URI Template | Description |
|--------------|-------------|
| gitlab://project/{projectId} | GitLab project metadata |
| gitlab://project/{projectId}/file/{filePath} | File content from a GitLab repository |
| atlassian://jira/issue/{issueKey} | Jira issue details |
| atlassian://jira/project/{projectKey} | Jira project details |
| atlassian://confluence/page/{pageId} | Confluence page content |
| atlassian://confluence/space/{spaceKey} | Confluence space details |
Server Endpoints
| Endpoint | Method | Auth | Description |
|----------|--------|------|-------------|
| /mcp | POST | Required | MCP protocol (JSON-RPC over Streamable HTTP) |
| /health | GET | Not required | Health check and provider status |
Health check:
curl http://127.0.0.1:8919/healthReturns:
{
"healthy": true,
"status": "ok",
"providers": {
"gitlab": "ready",
"atlassian": "ready"
},
"uptime": 3600,
"version": "2.3.1"
}Daemon Files
| File | Purpose |
|------|---------|
| ~/.padua/mcp-auth.json | Bearer token, port, PID, start time |
| ~/.padua/mcp-server.pid | Daemon process ID |
| ~/.padua/mcp-providers.json | Provider configuration (downloaded from S3) |
| ~/.padua/tokens.db | Encrypted OAuth tokens (AES-256-GCM) |
| ~/.padua/encryption.key | Auto-generated encryption key |
| ~/Library/Logs/padua-mcp/server.log | Daemon log (macOS) — upstream API calls, tool errors, token refresh |
| ~/.local/share/padua/logs/server.log | Daemon log (Linux) |
Diagnostics
padua doctorMCP-specific checks:
- Node.js version (>= 20.0.0)
- MCP provider configuration
- Token store integrity
- Encryption key availability
- Port availability
- Daemon health
- GitLab and Atlassian API connectivity
Token Migration
If upgrading from the standalone padua-mcp Go server:
padua doctor --migrate-tokensTroubleshooting
| Issue | Solution |
|-------|----------|
| Daemon not starting | Run padua doctor for diagnostics |
| Port 8919 in use | padua login auto-kills orphaned processes; or set mcp.port in ~/.padua/padua.config.json |
| Token issues | Delete ~/.padua/tokens.db and ~/.padua/encryption.key, then run padua login |
| Legacy daemon running | pkill -f padua-mcp-daemon |
| Tools not appearing | Verify padua login completed steps 5-7; check padua doctor for provider status |
| 401 Unauthorized | Ensure your IDE config includes the Authorization: Bearer padua-mcp-local header; check daemon log for upstream API errors |
| Debugging API errors | Check ~/Library/Logs/padua-mcp/server.log (macOS) or ~/.local/share/padua/logs/server.log (Linux). Set PADUA_MCP_LOG_LEVEL=debug for verbose output |
| MCP reconnection fails | Upgrade to v2.0.15+ — the daemon now handles ungraceful disconnects automatically |
Downgrade to 1.x
npm install -g @padua/cli@1
pkill -f padua-mcp-daemonInit Command
Interactive configuration wizard that discovers all AWS accounts and roles via SSO, then generates AWS CLI profiles.
Basic Usage
padua init # Standard initialization
padua init --keep-existing # Preserve custom non-Padua profiles
padua init --force # Skip confirmation promptsOptions
| Flag | Description |
|------|-------------|
| --force | Overwrite existing config without prompting |
| --keep-existing | Preserve non-Padua profiles in ~/.aws/config |
| --no-browser | Don't auto-open browser for SSO authentication |
| -v, --verbose | Show detailed progress information |
| --no-color | Disable colored output |
Note: --force and --keep-existing are mutually exclusive.
What It Does
- Prerequisite Check - Validates required tools are installed (AWS CLI v2, npm, Docker, Session Manager Plugin)
- Environment Variable Detection - Warns if AWS environment variables are set that may interfere with SSO
- SSO Authentication - Authenticates with AWS SSO or reuses cached token
- Account Discovery - Discovers all AWS accounts and roles available via SSO
- Role Selection - Prompts user to select which role to use for profiles
- Backup Creation - Creates timestamped backup of existing
~/.aws/config - Config Generation - Deletes old config and generates fresh profiles
- Profile Preservation - Optionally merges back custom non-Padua profiles
Backup Behavior
- Location:
~/.aws/config.backup.YYYYMMDD-HHMMSS - Auto-cleanup: Keeps last 5 backups, removes older ones automatically
- Restoration:
cp ~/.aws/config.backup.* ~/.aws/config
Profile Preservation
By default, padua init deletes all existing profiles to ensure a clean state. Use --keep-existing to preserve custom profiles:
padua init --keep-existingHow it works:
- Identifies Padua-managed profiles by
sso_session = paduareference - Preserves all other profiles (custom configurations)
- Merges custom profiles back after generating Padua profiles
Environment Variable Warnings
If AWS environment variables are detected, you'll see:
WARNING: AWS environment variables detected
The following environment variables may interfere with SSO authentication:
AWS_PROFILE=development
AWS_DEFAULT_REGION=us-east-1
To unset (bash/zsh):
unset AWS_PROFILE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_DEFAULT_REGION
Continue anyway? (y/N)Exit Codes
| Code | Meaning | |------|---------| | 0 | Success | | 1 | General error or mutually exclusive flags | | 2 | Missing required prerequisites | | 4 | Config write failed |
Troubleshooting
"SSO session 'padua' already exists"
- Run with
--forceflag to overwrite
Environment variables interfering
- Unset AWS variables before running init:
unset AWS_PROFILE AWS_ACCESS_KEY_ID AWS_SECRET_ACCESS_KEY AWS_SESSION_TOKEN AWS_DEFAULT_REGION
Lost custom profiles
- Check backup:
ls -la ~/.aws/config.backup.* - Restore backup:
cp ~/.aws/config.backup.20260128-143055 ~/.aws/config - Or run
padua init --keep-existingto preserve custom profiles
Login Command
Authenticate to AWS SSO, CodeArtifact (npm), and ECR (Docker) with a single command.
Automatically reads AWS_PROFILE environment variable when no --profile flag is provided (works with paws).
Basic Usage
padua login # Full login (SSO + CodeArtifact + ECR)
padua login --profile staging # Use specific AWS profile
padua login --sso-only # SSO only, skip CodeArtifact and ECROptions
| Flag | Description |
|------|-------------|
| -p, --profile <name> | AWS SSO profile to use |
| --sso-only | Only authenticate to SSO |
| --local | Write CodeArtifact config to project .npmrc instead of global ~/.npmrc |
| -v, --verbose | Show detailed output |
| -q, --quiet | Suppress non-error output |
| --no-color | Disable colored output |
Exit Codes
| Code | Meaning | |------|---------| | 0 | Success (SSO + at least one other service) | | 1 | SSO succeeded but CodeArtifact and ECR both failed | | 2 | SSO failed (other services not attempted) |
What padua login replaces
# Before: 3 separate commands
aws sso login --profile development
aws codeartifact login --tool npm --repository npm-repo --domain my-domain \
--domain-owner 123456789012 --region ap-southeast-2 --profile development
aws ecr get-login-password --region ap-southeast-2 | \
docker login --username AWS --password-stdin 123456789012.dkr.ecr.ap-southeast-2.amazonaws.com
# After: 1 command
padua loginExample Output
[1/7] AWS SSO ...
✓ authenticated (profile: paduafg-development)
[2/7] S3 Config ...
✓ downloaded
[3/7] CodeArtifact (npm) ...
✓ configured
[4/7] ECR (Docker) ...
✓ configured
[5/7] GitLab Auth ...
✓ authenticated
[6/7] Atlassian Auth ...
✓ authenticated
[7/7] MCP Daemon ...
✓ running (http://127.0.0.1:8919/mcp)
=== Login Results ===
SSO: ✓ OK
S3 Config: ✓ OK
CodeArtifact: ✓ OK
ECR: ✓ OK
GitLab: ✓ OK
Atlassian: ✓ OK
MCP Daemon: ✓ OK
Total: 7/7 services authenticatedConfiguration
Configuration is stored in ~/.padua/padua.config.json (created by padua init):
{
"defaultProfile": "development",
"region": "ap-southeast-2",
"codeartifact": {
"domain": "my-domain",
"domainOwner": "123456789012",
"repository": "npm-repo"
},
"ecr": {
"accountId": "123456789012",
"region": "ap-southeast-2"
}
}Profile Resolution Priority
- CLI flags (
--profile) PADUA_PROFILEenvironment variableAWS_PROFILEenvironment variabledefaultProfilein config file'default'
This means padua status automatically uses the profile set by paws or export AWS_PROFILE=....
Status Command
Check authentication status for all configured services with detailed AWS identity information.
Automatically reads AWS_PROFILE environment variable when no --profile flag is provided (works with paws).
Basic Usage
padua status # Check all services
padua status -p staging # Check with specific profile
padua status -q # Quiet mode (exit code only)Options
| Flag | Description |
|------|-------------|
| -p, --profile <name> | AWS profile to check |
| -q, --quiet | Only output if there are issues |
| --no-color | Disable colored output |
Example Output
AWS SSO
Status: Authenticated
Profile: paduafg-development
Account: 361485743373 (development)
Region: ap-southeast-2
Role: Developers
User: [email protected]
User ID: AROA123456789:[email protected]
CodeArtifact (npm)
Status: Authenticated
Registry: https://paduafg-361485743373.d.codeartifact.ap-southeast-2.amazonaws.com/npm/paduafg/
Expires: 12/4/2025, 7:30:00 PM (in 11 hours)
ECR (Docker)
Status: Authenticated
Registry: 361485743373.dkr.ecr.ap-southeast-2.amazonaws.comExit Codes
| Code | Meaning | |------|---------| | 0 | All services healthy | | 1 | One or more services have issues | | 2 | Configuration not found |
Doctor Command
Validate Padua CLI configuration and diagnose common issues. Helps troubleshoot problems with profiles, authentication, and prerequisites.
Basic Usage
padua doctor # Run all diagnostic checks
padua doctor --verbose # Show detailed diagnostic informationOptions
| Flag | Description |
|------|-------------|
| --fix | Attempt to auto-fix common issues (not yet implemented) |
| -v, --verbose | Show detailed diagnostic information |
| --no-color | Disable colored output |
Diagnostic Checks
The doctor command performs comprehensive validation:
- Config Validation - Verifies
~/.padua/padua.config.jsonexists and contains valid JSON - Config Schema - Validates field formats (account IDs, regions, domains, repositories)
- Profile Validation - Checks if
defaultProfileexists in~/.aws/config, suggests corrections for typos - Prerequisites - Checks AWS CLI, npm, Docker, Session Manager Plugin installation status and versions
- Authentication - Validates SSO, CodeArtifact, and ECR authentication status
- Installation - Compares current CLI version with latest published version on npm
- MCP Server - Node.js version (>= 20.0.0), MCP provider config, token store integrity, encryption key, port availability, daemon health, GitLab and Atlassian API connectivity
Use --migrate-tokens to migrate encrypted tokens from a legacy padua-mcp Go server database.
Example Output
🏥 Padua CLI Doctor
Config Validation
[✓] Config file: Found at ~/.padua/padua.config.json
[✓] Config schema: All fields valid
[✗] Default profile 'development' not found in ~/.aws/config
→ Did you mean 'paduafg-development'?
Prerequisites
[✓] AWS CLI: Installed (2.15.0)
[✓] npm: Installed (10.9.2)
[✓] Docker: Installed (29.1.3)
[⚠] Session Manager Plugin: Not installed
→ Required for tunneling features. Install: https://docs.aws.amazon.com/...
Authentication
[✓] SSO authentication: Authenticated as [email protected]
[✓] CodeArtifact authentication: Authenticated (project .npmrc)
[✓] ECR authentication: Authenticated
Installation
[⚠] CLI version: Current: 1.10.0, Latest: 1.11.0
→ Update with: npm install -g @padua/cli@latest
Summary: 1 error, 2 warningsExit Codes
| Code | Meaning | |------|---------| | 0 | All checks passed | | 1 | Issues or warnings found | | 2 | Config not found or invalid |
Use Cases
Troubleshooting login issues:
# Check why "padua login" fails
padua doctorVerifying setup after installation:
# Ensure all prerequisites are installed
padua doctorFinding profile typos:
# Get suggestions for misspelled profile names
padua doctor
# Example: Suggests 'paduafg-development' if you typed 'development'Profile Command
Interactive AWS profile selection with shell integration.
Basic Usage
padua profile # Interactive selection
padua profile --setup # Output shell function for paws command
padua profile --list-only # List profiles (for scripts)
padua profile --select-only # Select and output name onlyOptions
| Flag | Description |
|------|-------------|
| --setup | Output shell function for your shell profile |
| --list-only | Output profile names only (one per line) |
| --select-only | Interactive select, output only the name |
| --no-color | Disable colored output |
Shell Integration (paws)
paws is a shell function that switches AWS profiles by setting AWS_PROFILE in your current shell session. All Padua commands (padua login, padua status, padua tunnel) automatically pick up the active profile.
Installation
Run padua profile --setup and append the output to your shell profile:
# Bash
padua profile --setup >> ~/.bashrc && source ~/.bashrc
# Zsh
padua profile --setup >> ~/.zshrc && source ~/.zshrc
# PowerShell
padua profile --setup | Out-File -Append $PROFILE
. $PROFILEThis installs the paws function and tab completion for available profiles.
Usage
paws # Interactive profile selection (arrow keys)
paws <profile-name> # Switch to a specific profile directly
paws clear # Unset all AWS environment variables| Command | Description |
|---------|-------------|
| paws | Opens an interactive list of available SSO profiles |
| paws <name> | Sets AWS_PROFILE to the given profile name |
| paws clear | Unsets AWS_PROFILE, AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN, AWS_DEFAULT_REGION, AWS_REGION, and AWS_DEFAULT_PROFILE |
Tab Completion
Tab completion is included automatically with the shell function. Press Tab after typing paws to see available profiles and the clear subcommand.
Example Workflow
# Switch to development profile
paws paduafg-development
# AWS_PROFILE set to: paduafg-development
# Login using the active profile
padua login
# Check status
padua status
# Clear profile when done
paws clear
# AWS environment variables clearedTunnel Command
Create secure tunnels to AWS resources via SSM Session Manager.
Automatically reads AWS_PROFILE environment variable when no --profile flag is provided (works with paws).
Targets
| Target | Description | System Required |
|--------|-------------|-----------------|
| rds | Tunnel to RDS/Aurora databases | Yes (e.g., roma, padua-iam) |
| lb | Tunnel to internal ALB (dev.int.paduasolutions.net:443) | No |
| opensearch | Tunnel to AWS OpenSearch / Elasticsearch domain (port 443 → local 9200) | Yes (used as logical name in output) |
| elasticsearch | Alias for opensearch | Yes |
Basic Usage
# RDS tunnel (requires system argument)
padua tunnel roma rds # Interactive (prompts for port/cluster)
padua tunnel roma rds -p paduafg-development # Use specific profile
# Load balancer tunnel (no system needed)
padua tunnel lb # Interactive (prompts for port, default 8443)
padua tunnel lb --local-port 9443 # Use specific local portOptions
| Flag | Description |
|------|-------------|
| -p, --profile <name> | AWS profile to use |
| --local-port <port> | Local port for the tunnel |
| --cluster <name> | RDS cluster or instance name (RDS only) |
| --domain <name> | OpenSearch domain name (OpenSearch only) — skips interactive selection |
| -v, --verbose | Show detailed output |
| --no-color | Disable colored output |
RDS System Configuration
Different systems use different EC2 instances as tunnel endpoints:
| System | EC2 Tag | Default Port | Default Cluster |
|--------|---------|--------------|-----------------|
| roma | bastion-host | 3306 (MySQL) | roma-backend |
| (others) | ${alias}-jumpbox | 5432 (PostgreSQL) | (none) |
Note: The LB tunnel resolves the account alias via
aws sts get-caller-identityand looks up the returned account ID in the embeddedPADUA_ACCOUNT_ALIASESmap (src/shared/aws-accounts.ts). The jumpbox EC2 Name tag is constructed as<alias>-jumpbox(e.g. account361485743373→ aliasdevelopment→ tagdevelopment-jumpbox). If the account ID is not present in the map, the command fails with a clear error listing known accounts — there is no silent fallback.
LB Tunnel Usage
The internal ALB uses path-based routing for most services. Once the tunnel is running:
# Path-based services (most services)
curl -k https://localhost:8443/echo/test
curl -k https://localhost:8443/wealth-summaries/healthz
curl -k https://localhost:8443/entity-management/api/v1/status
# Host-based services (permify)
curl -k https://localhost:8443/v1/permissions/check \
-H "Host: permify.dev.int.paduasolutions.net"Example Output (RDS)
Checking port 3306 availability...
✓ Port 3306 is available
Looking up bastion-host instance...
✓ Found instance: i-0abc123def456
Looking up RDS endpoint for roma-backend...
✓ Found endpoint: roma-backend.cluster-xxx.ap-southeast-2.rds.amazonaws.com
Starting tunnel...
System: roma
Profile: paduafg-development
Local port: 3306
Remote: roma-backend.cluster-xxx.ap-southeast-2.rds.amazonaws.com:3306
Via: i-0abc123def456 (bastion-host)
Press Ctrl+C to close the tunnelExample Output (LB)
Checking port 8443 availability...
✓ Port 8443 is available
Looking up jumpbox instance...
✓ Found instance: i-0abc123def456
Starting tunnel...
Profile: paduafg-development
Local port: 8443
Remote: dev.int.paduasolutions.net:443
Via: i-0abc123def456 (development-jumpbox)
Usage (path-based services):
curl -k https://localhost:8443/<service>/path
e.g. curl -k https://localhost:8443/echo/test
Usage (host-based services like permify):
curl -k https://localhost:8443/path -H "Host: <service>.dev.int.paduasolutions.net"
Press Ctrl+C to close the tunnelOpenSearch Tunnel Usage
# Interactive (lists domains, prompts for selection)
padua tunnel logs opensearch
padua tunnel logs opensearch -p paduafg-development
# Skip selection
padua tunnel logs opensearch --domain my-domain
padua tunnel logs opensearch --domain my-domain --local-port 9201
# elasticsearch alias works identically
padua tunnel logs elasticsearch --domain legacy-es-domainThe first positional argument (e.g. logs) is a logical system name shown in output — it does not affect domain discovery. Domains are listed via aws opensearch list-domain-names for the current profile/region.
Endpoint resolution: Endpoints.vpc is preferred. If the domain is public-only, the public Endpoint is used and a warning is printed. If neither exists, the command throws.
Ports: Remote is always 443 (HTTPS). Default local port is 9200.
Curl Examples
# Cluster health
curl -k https://localhost:9200/
# List indices
curl -k https://localhost:9200/_cat/indices?v
# OpenSearch Dashboards (formerly Kibana)
open https://localhost:9200/_dashboards/TLS and SigV4 Notes
-kis required. The domain's TLS certificate is for*.<region>.es.amazonaws.com, notlocalhost.curlrejects the mismatch without-k(or--insecure).- SigV4 over the tunnel breaks IAM signing. AWS SigV4 signs the
Hostheader. The signed host is<domain>.<region>.es.amazonaws.com, but the tunneled request hitslocalhost:9200, so signature verification fails on the AWS side.- Workarounds:
- Use a domain with Fine-Grained Access Control (FGAC) and authenticate with basic auth (
-u user:pass), not IAM. - Or use a domain with an open access policy (no auth) for read-only browse from a VPC.
- If you must use IAM, query the domain directly without a tunnel (from an EC2 in the VPC or via a SigV4-aware proxy).
- Use a domain with Fine-Grained Access Control (FGAC) and authenticate with basic auth (
- Workarounds:
Exec Command
Open an interactive shell in a running ECS container via SSM Execute Command.
Basic Usage
padua exec # Interactive (prompts for cluster/service/task/container)
padua exec -c my-cluster -s my-service # Specify cluster and service
padua exec -c my-cluster -s my-service -t abc123 --container app # Fully non-interactiveOptions
| Flag | Description |
|------|-------------|
| -p, --profile <name> | AWS profile to use |
| -c, --cluster <name> | ECS cluster name |
| -s, --service <name> | ECS service name |
| -t, --task <id> | ECS task ID |
| --container <name> | Container name |
| --command <cmd> | Command to run (default: /bin/bash) |
| -v, --verbose | Show detailed output |
| --no-color | Disable colored output |
Auto-selects when only one option exists at each level (cluster, service, task, container).
Bedrock Command
Configure Claude Code to use AWS Bedrock inference inside the paduafg-production account. All inference stays in ap-southeast-2 (AU data residency), and every bedrock:InvokeModel* call is logged in CloudTrail under paduafg-production.
Prerequisites
- Active
paduafg-productionSSO session (padua login -p paduafg-production) - IAM permissions:
bedrock:ListInferenceProfiles,bedrock:InvokeModel,bedrock:InvokeModelWithResponseStream,bedrock:GetInferenceProfile
Setup (one-time)
# Install pbedrock shell function
eval "$(padua bedrock --setup)"
# Add permanently to your shell profile
padua bedrock --setup >> ~/.zshrc # or ~/.bashrc
source ~/.zshrcDaily Use
pbedrock on # Enable Bedrock mode (discovers profiles, sets 8 env vars)
pbedrock off # Disable Bedrock mode (restores previous env)
pbedrock # Toggle
pbedrock status # Show current stateOr directly:
eval "$(padua bedrock enable --eval -p paduafg-production)"
eval "$(padua bedrock disable --eval)"
padua bedrock statusOptions
| Flag | Description |
|------|-------------|
| -p, --profile <name> | AWS SSO profile (default: paduafg-production) |
| -r, --region <region> | AWS region (default: ap-southeast-2) |
| --config-dir <path> | Custom Claude config directory |
| --eval | Output shell export statements only |
| --allow-non-prod | Allow non-production profiles |
| --setup | Output pbedrock shell function |
| --shell <shell> | Shell type for --setup: zsh, bash, or pwsh |
| -v, --verbose | Verbose output (never dumps env vars) |
| --no-color | Disable colored output |
Security
- Production-only default — non-
paduafg-productionprofiles are rejected unless--allow-non-prodis passed - Region pinned to
ap-southeast-2; inference profile ARNs must start withap-southeast- - All exported values are shell-escaped to prevent injection via
eval $HOMEcontainment guard on the default config directory- Subprocess env hardened via
getSubprocessEnv()whitelist — no secret leakage to child processes - Verbose mode never dumps environment variables
What pbedrock on sets
| Variable | Value |
|----------|-------|
| CLAUDE_CODE_USE_BEDROCK | 1 |
| CLAUDE_CONFIG_DIR | ~/.claude-bedrock |
| CLAUDE_CONFIG_DIR_BEFORE_BEDROCK | Previous CLAUDE_CONFIG_DIR value |
| ANTHROPIC_MODEL | Latest APAC claude-3-5-sonnet profile ID |
| ANTHROPIC_DEFAULT_OPUS_MODEL | Latest APAC claude-opus profile ID |
| ANTHROPIC_DEFAULT_SONNET_MODEL | Latest APAC claude-3-5-sonnet profile ID |
| ANTHROPIC_DEFAULT_HAIKU_MODEL | Latest APAC claude-3-5-haiku profile ID |
| AWS_REGION | ap-southeast-2 |
Planned Features
The following commands are planned for future releases:
padua tunnel ec2 <name> # SSM session to EC2 instanceDevelopment
git clone <repository-url>
cd padua-cli
npm install
npm run build
npm link # Makes 'padua' available globally
npm test # Run tests
npm run test:coverage # Run tests with coverageLicense
MIT
