Aperture CLI
Aperture is a command-line interface (CLI) that dynamically generates commands from OpenAPI 3.x specifications. It's designed to provide a secure, reliable, and introspectable "tool-use" endpoint for autonomous AI agents and automated systems.
Table of Contents
Features
- OpenAPI-Native: Directly consumes standard OpenAPI 3.x documents as the single source of truth
- Dynamic & Performant: Generates commands at runtime from pre-validated, cached API specifications
- Agent-First Design: Optimized for programmatic use with structured I/O, JSON output modes, and actionable errors
- Secure & Robust: Enforces strict separation of configuration from secrets using environment variables
- Spec Validation: Validates OpenAPI specs during registration with clear error messages for unsupported features
- Parameter References: Full support for OpenAPI parameter references (
$ref) for DRY specifications - Server Variables: Support for OpenAPI server URL templates with validation and defaults
- Batch Processing: Execute multiple operations concurrently with rate limiting and error handling
- Response Caching: Intelligent caching with TTL support for improved performance
- Advanced Output: Multiple output formats (JSON, YAML, table) with JQ-based filtering
- Flag-Based Syntax: Consistent
--flagsyntax for all parameters (with legacy positional support)
Architecture
Aperture follows a two-phase approach:
- Setup Phase (
aperture config add): Parses, validates, and caches OpenAPI specifications - Runtime Phase (
aperture <context> <command>): Loads cached specs for fast command generation and execution
Configuration Structure
~/.config/aperture/
├── specs/ # Original OpenAPI specification files
├── .cache/ # Pre-processed binary cache files
└── config.toml # Global configuration (optional)
Security Model
Authentication is handled through custom x-aperture-secret extensions in OpenAPI specs that map security schemes to environment variables.
Supported Authentication Schemes
- API Key (header, query, or cookie)
components:
securitySchemes:
apiKey:
type: apiKey
in: header
name: X-API-Key
x-aperture-secret:
source: env
name: API_KEY
- HTTP Bearer Token
components:
securitySchemes:
bearerAuth:
type: http
scheme: bearer
x-aperture-secret:
source: env
name: API_TOKEN
- HTTP Basic Authentication
components:
securitySchemes:
basicAuth:
type: http
scheme: basic
x-aperture-secret:
source: env
name: BASIC_CREDENTIALS # Format: username:password (will be base64 encoded automatically)
- Custom HTTP Schemes (Token, DSN, ApiKey, proprietary schemes)
components:
securitySchemes:
# Common alternative to Bearer
tokenAuth:
type: http
scheme: Token
x-aperture-secret:
source: env
name: API_TOKEN
# Sentry-style DSN authentication
dsnAuth:
type: http
scheme: DSN
x-aperture-secret:
source: env
name: SENTRY_DSN
# Any custom scheme name
customAuth:
type: http
scheme: X-CompanyAuth-V2
x-aperture-secret:
source: env
name: COMPANY_TOKEN
All custom HTTP schemes are treated as bearer-like tokens and formatted as: Authorization: <scheme> <token>
Unsupported Authentication
The following authentication types require complex flows and are not supported:
- OAuth2 (all flows)
- OpenID Connect
- HTTP Negotiate (Kerberos/NTLM)
- HTTP OAuth scheme
Partial API Support
Starting from v0.1.4, Aperture handles APIs with unsupported features gracefully:
-
Non-Strict Mode (Default): APIs containing unsupported authentication schemes or content types are accepted
- Only endpoints that require unsupported features are skipped
- Endpoints with multiple authentication options (where at least one is supported) remain available
- Clear warnings show which endpoints are skipped and why
-
Strict Mode: Use the
--strictflag withaperture config addto reject specs with any unsupported features
This allows you to use most endpoints of an API even if some require unsupported authentication methods or content types:
# Default behavior - accepts spec, skips unsupported endpoints with warnings
# Strict mode - rejects spec if any unsupported features found
Dynamic Secret Configuration
Starting from v0.1.4, Aperture supports dynamic authentication configuration without modifying OpenAPI specifications. This allows you to:
- Use unmodified third-party OpenAPI specs - No need to fork and add
x-aperture-secretextensions - Easy credential management - Configure authentication through simple CLI commands
- Environment flexibility - Use different credentials per environment without spec changes
- Credential rotation - Update environment variables without editing specifications
Configure secrets with CLI commands:
# Direct configuration
# Interactive configuration (guided setup)
# List configured secrets
Priority system:
- Config-based secrets (set via CLI commands) take highest priority
- x-aperture-secret extensions (in OpenAPI specs) used as fallback
- Clear error messages when neither is available
This feature maintains complete backward compatibility - existing x-aperture-secret extensions continue to work exactly as before, but can now be overridden by config-based settings.
Parameter References
Aperture fully supports OpenAPI parameter references, allowing you to define reusable parameters:
components:
parameters:
userId:
name: userId
in: path
required: true
schema:
type: string
paths:
/users/{userId}:
get:
parameters:
- $ref: '#/components/parameters/userId'
Installation
Using Cargo (Recommended)
Build from Source
Optional Features
Aperture supports optional features that can be enabled during compilation:
JQ Support
Aperture provides JSON filtering capabilities through the --jq flag:
Basic Filtering (Default) Without any special features, Aperture supports basic field access:
# Simple field extraction
# Nested field access
Advanced Filtering (Experimental)
The jq feature flag enables advanced JSON filtering using a pure Rust JQ implementation:
# Build with JQ support (currently has known issues - see issue #25)
⚠️ Known Issue: The advanced JQ feature (--features jq) currently has a bug where filters return the entire JSON document instead of filtered results. See issue #25 for details. For production use, we recommend using the default build without the jq feature flag.
Supported without jq feature:
- Basic field access:
.field,.nested.field - Array index access:
.items[0]
Requires jq feature (currently broken):
- Complex filters:
.[] | select(),map(), array slicing - Pipe operations and transformations
- Advanced JQ syntax
Getting Started
Basic Usage
# Register an API specification
# Register with strict validation (rejects specs with any unsupported features)
# List available APIs
# Configure authentication secrets (v0.1.4)
# Execute API commands (dynamically generated from spec)
Base URL Management
Aperture provides flexible base URL configuration for different environments:
# Set a custom base URL for an API (overrides spec and environment variables)
# Configure environment-specific URLs
# View current URL configuration
# List all configured URLs across APIs
# Use environment-specific URL
APERTURE_ENV=staging
URL Resolution Priority:
- Explicit test parameter (for testing)
- Per-API configuration (with environment support)
APERTURE_BASE_URLenvironment variable (global override)- OpenAPI spec server URL (default)
- Fallback URL (
https://api.example.com)
Server URL Template Variables
Starting from v0.1.4, Aperture supports OpenAPI server URL templates with variables:
# For APIs with templated server URLs like https://{region}.api.example.com/{version}
# Provide template variables using --server-var
# Variables with enum constraints are validated
# Variables with defaults can be overridden
OpenAPI Specification Example:
servers:
- url: https://{region}.api.example.com/{version}
variables:
region:
default: us
enum:
description: API region
version:
default: v1
description: API version
Features:
- Validation: Enum values are validated, invalid values are rejected
- Defaults: Variables with defaults are optional, others are required
- URL Encoding: Variable values are automatically URL-encoded
- Error Messages: Clear guidance when variables are missing or invalid
Agent-Friendly Features
# Get JSON description of all available commands
# Output errors as structured JSON
# Preview request without execution
# Add idempotency key for safe retries
# Get specific user with flag-based syntax
Advanced Output Formatting
Aperture supports multiple output formats and data filtering:
# Output as formatted table
# Output as YAML
# Extract specific fields with JQ filtering (basic - works by default)
# Nested field access (works by default)
# Complex JQ transformations (requires --features jq, currently broken)
# aperture api my-api get-data --jq '.items | map(select(.active)) | .[0:5]'
# JQ filtering with --describe-json (basic access works)
Batch Operations & Automation
For high-volume automation, Aperture supports batch processing with concurrency controls:
# Execute multiple operations from a batch file
# Rate limiting for batch operations
# Analyze batch results with JQ filtering (requires --json-errors)
# Basic field access (works by default):
# Complex filters (require --features jq, currently broken):
# aperture api my-api --batch-file operations.json --json-errors --jq '.batch_execution_summary.operations[] | select(.success == false)'
# aperture api my-api --batch-file operations.json --json-errors --jq '{total: .batch_execution_summary.total_operations, failed: .batch_execution_summary.failed_operations}'
Example batch file (JSON):
Response Caching
Improve performance with intelligent response caching:
# Enable caching with default TTL (300 seconds)
# Custom cache TTL
# Disable caching
# Manage cache
Command Syntax
Aperture now uses flag-based syntax by default for all parameters:
# Default flag-based syntax (recommended)
# Legacy positional syntax (backwards compatibility)
Exit Codes
Aperture follows standard CLI conventions for exit codes:
- 0: Success - all operations completed successfully
- 1: Failure - one or more operations failed, including:
- API request failures (4xx, 5xx errors)
- Network connection errors
- Authentication failures
- Batch operations with any failed requests
For batch operations, Aperture exits with code 1 if ANY operation fails, making it easy to detect failures in CI/CD pipelines:
# Check batch success/failure
if [; then
else
fi
# Continue despite failures
||
Development
This project is built with Rust and follows Test-Driven Development practices.
Prerequisites
- Rust (latest stable version)
- Cargo
Development Commands
# Build the project
# Run all tests
# Run tests for specific module
# Format code
# Check formatting and linting
# Run with debug output
RUST_LOG=debug
Testing
The project uses comprehensive testing strategies:
- Unit Tests: Located in
tests/directory - Integration Tests: End-to-end CLI testing using
assert_cmd - HTTP Mocking: API interaction testing using
wiremock
# Run integration tests
# Run with HTTP mocking
Project Status
Experimental: This project is in an experimental phase. While core functionality is implemented and tested, the API and features may change as we iterate based on usage and feedback. See docs/architecture.md for the complete software design specification.
License
Licensed under the MIT License. See LICENSE for details.