How the Macro Authentication Service Handles JWT Tokens: Implementation Guide

The Macro authentication service leverages the macro_auth crate to decode and verify JWTs using JwtValidationArgs for configuration and MacroAuthJwtValidator for enforcement, loading signing secrets from AWS Secrets Manager and validating tokens on every request via Axum middleware.

The macro-inc/macro repository implements a production-grade JWT authentication flow within its authentication service. By combining the macro_auth library with asynchronous secret management, the service dynamically loads validation parameters at startup and enforces cryptographic token verification across all API endpoints.

JWT Validation Architecture Overview

The authentication flow centers on three core components defined in the macro_auth crate: the configuration struct JwtValidationArgs, the validator implementation MacroAuthJwtValidator, and the middleware handler that executes validation per request. In services/authentication_service/src/main.rs, the service initializes these components during startup, creating a centralized authorization state that Axum injects into request handlers.

The JwtValidationArgs struct (imported at line 36) manages validation parameters including the expected issuer, audience, and HS256 signing secret. This configuration object feeds into MacroAuthJwtValidator, which implements the MacroAuthorizationState trait used throughout the application to gate access to protected resources.

Configuring JWT Validation with JwtValidationArgs

Before processing requests, the service constructs validation arguments that define acceptable token criteria and secure key material.

Loading Secrets from AWS Secrets Manager

The JwtValidationArgs struct retrieves the JWT signing secret asynchronously during initialization. In production environments, it fetches the secret from AWS Secrets Manager, while local development uses a test secret. This initialization occurs at lines 176-179 of services/authentication_service/src/main.rs:

let jwt_args = JwtValidationArgs::new_with_secret_manager(
    config.environment,
    &secretsmanager_client,
).await?;

Validation Parameters and Constraints

The JwtValidationArgs instance configures validation rules including the expected issuer (iss), audience (aud), and expiry checks. These constraints ensure tokens match the specific service configuration before cryptographic verification occurs. The validator rejects tokens with invalid signatures, expired timestamps, or mismatched claims according to these parameters.

Implementing the Validator with MacroAuthJwtValidator

Once configured, the JwtValidationArgs feeds into MacroAuthJwtValidator, which serves as the concrete implementation of the authorization interface. Lines 199-202 of the main service file demonstrate this composition:

let auth_state = MacroAuthorizationState::new(Arc::new(AuthorizationService::new(
    MacroAuthJwtValidator::new(jwt_args.clone()),
    InternalAuthConfig { api_key: internal_api_key.to_string(), default_user_id: None },
    macro_authorization::NoBotAuthorizer,
)));

This architecture separates token validation logic from business logic, allowing the MacroAuthJwtValidator to focus exclusively on cryptographic verification while the AuthorizationService handles higher-level access control policies.

Processing Requests with Middleware Validation

Incoming requests undergo validation through Axum middleware defined in services/mcp_auth_proxy/src/inbound/middleware.rs. The middleware extracts the Bearer token from the Authorization header and invokes the validation handler provided by the macro_auth crate.

At line 89, the middleware calls the validation function:

let jwt_token = match handler(&jwt_args, &token) {
    // Token valid: proceed with request
    // Token invalid: return 401 Unauthorized
};

The handler function, defined in crates/macro_auth/src/middleware/decode_jwt.rs, performs the actual validation:

  • Verifies the HS256 signature against the loaded secret
  • Checks the iss claim against the configured issuer
  • Validates expiration timestamps
  • Extracts the user ID claim for downstream use

The middleware returns a typed JwtToken struct on success, which handlers use to identify the authenticated user.

Summary

Frequently Asked Questions

Where does the Macro authentication service store JWT signing secrets?

The service retrieves JWT signing secrets from AWS Secrets Manager in production environments, or uses local test secrets during development. This occurs during startup in services/authentication_service/src/main.rs when calling JwtValidationArgs::new_with_secret_manager(), which accepts the environment configuration and secrets manager client as parameters.

What validation algorithm does the Macro authentication service use for JWTs?

The implementation uses HS256 (HMAC with SHA-256) for signature verification. The handler function in crates/macro_auth/src/middleware/decode_jwt.rs validates the token signature against the secret loaded into JwtValidationArgs, ensuring only tokens signed with the correct key are accepted.

How does the authentication service inject JWT validation into API requests?

The service uses Axum's state injection pattern. It creates a MacroAuthorizationState containing the MacroAuthJwtValidator in services/authentication_service/src/main.rs, then applies middleware at services/mcp_auth_proxy/src/inbound/middleware.rs that extracts the Bearer token from the Authorization header and calls the validation handler for every protected request.

Can the JWT validation parameters be configured for different environments?

Yes. The JwtValidationArgs struct accepts an environment parameter that determines whether to load secrets from AWS Secrets Manager or use local test credentials. This allows the same codebase to operate in development, staging, and production with different validation configurations without code changes.

Have a question about this repo?

These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:

Share the following with your agent to get started:
curl -s "https://instagit.com/install.md"

Works with
Claude Codex Cursor VS Code OpenClaw Any MCP Client

Maintain an open-source project? Get it listed too →