# Moose / Apis / Auth Documentation – Python ## Included Files 1. moose/apis/auth/auth.mdx ## API Authentication & Security Source: moose/apis/auth/auth.mdx Secure your Moose API endpoints with JWT tokens or API keys # API Authentication & Security Moose supports two authentication mechanisms for securing your API endpoints: - **[API Keys](#api-key-authentication)** - Simple, static authentication for internal applications and getting started - **[JWT (JSON Web Tokens)](#jwt-authentication)** - Token-based authentication for integration with existing identity providers Choose the method that fits your use case, or use both together with custom configuration. ## Do you want to use API Keys? API keys are the simplest way to secure your Moose endpoints. They're ideal for: - Internal applications and microservices - Getting started quickly with authentication - Scenarios where you control both client and server ### How API Keys Work API keys use PBKDF2 HMAC SHA256 hashing for secure storage. You generate a token pair (plain-text and hashed) using the Moose CLI, store the hashed version in environment variables, and send the plain-text version in your request headers. ### Step 1: Generate API Keys Generate tokens and hashed keys using the Moose CLI: ```bash moose generate hash-token ``` **Output:** - **ENV API Keys**: Hashed key for environment variables (use this in your server configuration) - **Bearer Token**: Plain-text token for client applications (use this in `Authorization` headers) Use the **hashed key** for environment variables and `moose.config.toml`. Use the **plain-text token** in your `Authorization: Bearer token` headers. ### Step 2: Configure API Keys with Environment Variables Set environment variables with the **hashed** API keys you generated: ```bash # For ingest endpoints export MOOSE_INGEST_API_KEY='your_pbkdf2_hmac_sha256_hashed_key' # For analytics endpoints export MOOSE_CONSUMPTION_API_KEY='your_pbkdf2_hmac_sha256_hashed_key' # For admin endpoints export MOOSE_ADMIN_TOKEN='your_plain_text_token' ``` Or set the admin API key in `moose.config.toml`: ```toml filename="moose.config.toml" [authentication] admin_api_key = "your_pbkdf2_hmac_sha256_hashed_key" ``` Storing the `admin_api_key` (which is a PBKDF2 HMAC SHA256 hash) in your `moose.config.toml` file is an acceptable practice, even if the file is version-controlled. This is because the actual plain-text Bearer token (the secret) is not stored. The hash is computationally expensive to reverse, ensuring that your secret is not exposed in the codebase. ### Step 3: Make Authenticated Requests All authenticated requests require the `Authorization` header with the **plain-text token**: ```bash # Using curl curl -H "Authorization: Bearer your_plain_text_token_here" \ https://your-moose-instance.com/ingest/YourDataModel # Using JavaScript fetch('https://your-moose-instance.com/api/endpoint', { headers: { 'Authorization': 'Bearer your_plain_text_token_here' } }) ``` ## Do you want to use JWTs? JWT authentication integrates with existing identity providers and follows standard token-based authentication patterns. Use JWTs when: - You have an existing identity provider (Auth0, Okta, etc.) - You need user-specific authentication and authorization - You want standard OAuth 2.0 / OpenID Connect flows ### How JWT Works Moose validates JWT tokens using RS256 algorithm with your identity provider's public key. You configure the expected issuer and audience, and Moose handles token verification automatically. ### Step 1: Configure JWT Settings #### Option A: Configure in `moose.config.toml` ```toml filename=moose.config.toml [jwt] # Your JWT public key (PEM-formatted RSA public key) secret = """ -----BEGIN PUBLIC KEY----- MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAy... -----END PUBLIC KEY----- """ # Expected JWT issuer issuer = "https://my-auth-server.com/" # Expected JWT audience audience = "my-moose-app" ``` The `secret` field should contain your JWT **public key** used to verify signatures using RS256 algorithm. #### Option B: Configure with Environment Variables You can also set these values as environment variables: ```bash filename=".env" copy MOOSE_JWT_PUBLIC_KEY=your_jwt_public_key # PEM-formatted RSA public key (overrides `secret` in `moose.config.toml`) MOOSE_JWT_ISSUER=your_jwt_issuer # Expected JWT issuer (overrides `issuer` in `moose.config.toml`) MOOSE_JWT_AUDIENCE=your_jwt_audience # Expected JWT audience (overrides `audience` in `moose.config.toml`) ``` ### Step 2: Make Authenticated Requests Send requests with the JWT token in the `Authorization` header: ```bash # Using curl curl -H "Authorization: Bearer your_jwt_token_here" \ https://your-moose-instance.com/ingest/YourDataModel # Using JavaScript fetch('https://your-moose-instance.com/api/endpoint', { headers: { 'Authorization': 'Bearer your_jwt_token_here' } }) ``` ## Want to use both? Here's the caveats You can configure both JWT and API Key authentication simultaneously. When both are configured, Moose's authentication behavior depends on the `enforce_on_all_*` flags. ### Understanding Authentication Priority #### Default Behavior (No Enforcement) By default, when both JWT and API Keys are configured, Moose tries JWT validation first, then falls back to API Key validation: ```toml filename="moose.config.toml" [jwt] # JWT configuration secret = "..." issuer = "https://my-auth-server.com/" audience = "my-moose-app" # enforce flags default to false ``` ```bash filename=".env" # API Key configuration MOOSE_INGEST_API_KEY='your_pbkdf2_hmac_sha256_hashed_key' MOOSE_CONSUMPTION_API_KEY='your_pbkdf2_hmac_sha256_hashed_key' ``` **For Ingest Endpoints (`/ingest/*`)**: - Attempts JWT validation first (RS256 signature check) - Falls back to API Key validation (PBKDF2 HMAC SHA256) if JWT fails **For Analytics Endpoints (`/api/*`)**: - Same fallback behavior as ingest endpoints This allows you to use either authentication method for your clients. #### Enforcing JWT Only If you want to **only** accept JWT tokens (no API key fallback), set the enforcement flags: ```toml filename="moose.config.toml" [jwt] secret = "..." issuer = "https://my-auth-server.com/" audience = "my-moose-app" # Only accept JWT, no API key fallback enforce_on_all_ingest_apis = true enforce_on_all_consumptions_apis = true ``` **Result**: When enforcement is enabled, API Key authentication is disabled even if the environment variables are set. Only valid JWT tokens will be accepted. ### Common Use Cases #### Use Case 1: Different Auth for Different Endpoints Configure JWT for user-facing analytics endpoints, API keys for internal ingestion: ```toml filename="moose.config.toml" [jwt] secret = "..." issuer = "https://my-auth-server.com/" audience = "my-moose-app" enforce_on_all_consumptions_apis = true # JWT only for /api/* enforce_on_all_ingest_apis = false # Allow fallback for /ingest/* ``` ```bash filename=".env" MOOSE_INGEST_API_KEY='hashed_key_for_internal_services' ``` #### Use Case 2: Migration from API Keys to JWT Start with both configured, no enforcement. Gradually migrate clients to JWT. Once complete, enable enforcement: ```toml filename="moose.config.toml" [jwt] secret = "..." issuer = "https://my-auth-server.com/" audience = "my-moose-app" # Start with both allowed during migration enforce_on_all_ingest_apis = false enforce_on_all_consumptions_apis = false # Later, enable to complete migration # enforce_on_all_ingest_apis = true # enforce_on_all_consumptions_apis = true ``` ### Admin Endpoints Admin endpoints use API key authentication exclusively (configured separately from ingest/analytics endpoints). **Configuration precedence** (highest to lowest): 1. `--token` CLI parameter (plain-text token) 2. `MOOSE_ADMIN_TOKEN` environment variable (plain-text token) 3. `admin_api_key` in `moose.config.toml` (hashed token) **Example:** ```bash # Option 1: CLI parameter moose remote plan --token your_plain_text_token # Option 2: Environment variable export MOOSE_ADMIN_TOKEN='your_plain_text_token' moose remote plan # Option 3: Config file # In moose.config.toml: # [authentication] # admin_api_key = "your_pbkdf2_hmac_sha256_hashed_key" ``` ## Security Best Practices - **Never commit plain-text tokens to version control** - Always use hashed keys in configuration files - **Use environment variables for production** - Keep secrets out of your codebase - **Generate unique tokens for different environments** - Separate development, staging, and production credentials - **Rotate tokens regularly** - Especially for long-running production deployments - **Choose the right method for your use case**: - Use **API Keys** for internal services and getting started - Use **JWT** when integrating with identity providers or need user-level auth - **Store hashed keys safely** - The PBKDF2 HMAC SHA256 hash in `moose.config.toml` is safe to version control, but the plain-text token should only exist in secure environment variables or secret management systems Never commit plain-text tokens to version control. Use hashed keys in configuration files and environment variables for production.