Security Considerations for Macro Inc.: Defense-in-Depth in Rust Microservices

Macro Inc. implements defense-in-depth security through compile-time secret validation, JWT middleware, internal API key authentication, and strict logging discipline across its Rust microservices running on AWS.

Macro Inc. is a collection of Rust microservices deployed on AWS that treats security as a foundational architectural layer rather than an afterthought. Understanding the security considerations for Macro Inc. reveals a defense-in-depth strategy spanning secret management, compile-time validation, and zero-trust networking. The codebase achieves this through a unified macro_env_var crate and strict middleware-based authentication patterns.

Centralized Secret Management with the macro_env_var Crate

All configuration values—including API keys, database URLs, and JWT signing secrets—flow through the macro_env_var crate. This centralized approach ensures that secrets never appear as plain literals in the source code and are loaded in a single, audited location.

In crates/macro_env_var/src/lib.rs (lines 1‑80, 85‑120), the crate provides the env_var! macro and functions read_env and maybe_read_env. These utilities first check for a JSON blob in the APP_SECRETS_JSON environment variable (populated by Doppler) and fall back to the standard process environment. This dual-source pattern guarantees that production secrets remain decoupled from the repository while allowing local development to use standard environment variables.

Compile-Time Validation of Configuration

The env_var! macro generates types that distinguish between Runtime and Comptime loading. When a developer invokes new_comptime() on a generated type, the compiler validates the secret's presence at build time. If a required secret is missing, the build fails immediately, preventing accidental deployment without necessary credentials.

This compile-time guarantee is implemented in crates/macro_env_var/src/lib.rs (lines 85‑130). The discriminator forces developers to handle configuration errors during the CI/CD pipeline rather than at runtime in production.

JWT Authentication for External Requests

Incoming HTTP requests are protected by the macro_auth middleware, which validates JSON Web Tokens before any business logic executes. The decode_jwt function in crates/macro_auth/src/middleware/decode_jwt.rs (lines 1‑80) verifies that tokens are signed with the secret loaded via macro_env_var. Invalid tokens are rejected at the edge, ensuring that unauthenticated requests never reach internal handlers.

use macro_env_var::env_vars;

env_vars! {
    pub struct JwtSigningKey;
}

// Load the key at runtime with fallback to APP_SECRETS_JSON
let jwt_key = JwtSigningKey::new()?;

// Apply the middleware to protect routes
async fn auth_layer<B>(req: axum::http::Request<B>, next: axum::handler::Next<B>) -> impl IntoResponse {
    macro_auth::middleware::decode_jwt(req, next, &jwt_key).await
}

Service-to-Service Authorization via Internal API Keys

For internal communication, services exchange signed internal API keys that are also loaded through macro_env_var. The validate_internal_key function in crates/macro_auth/src/internal_api_key.rs (lines 1‑50) checks these keys and injects a trusted UserId into the request context.

This mechanism allows services to authenticate each other without exposing user-level credentials or relying on network perimeter security alone. Each microservice treats internal requests with the same skepticism as external ones, enforcing a zero-trust model inside the cluster.

Database Access Control and SQL Injection Prevention

Database credentials are retrieved through macro_env_var in each service's configuration. For example, services/document_storage_service/src/config.rs uses the env_vars! macro to load connection strings securely.

The codebase never concatenates raw strings into SQL queries. Instead, it uses SQLx with compile-time checked macros like query! and query_as!. This practice ensures that queries match the current database schema and eliminates SQL injection vectors by treating all parameters as bound values rather than interpolated strings.

AWS Credential Hygiene and CI/CD Security

Static AWS credentials are confined exclusively to CI pipelines. In tooling/xtask/crates/xtask_workflows/src/workflows/deploy_all_services.rs (line 319), deploy scripts use explicit static keys only within controlled CI environments. These keys are injected via macro_env_var and never committed to the repository.

Runtime services obtain temporary credentials from the AWS instance metadata service. This distinction limits the blast radius of any potential credential leak, as static keys cannot be extracted from running production containers.

Logging Discipline to Prevent Secret Leakage

The codebase enforces strict patterns to prevent accidental secret exposure in logs. All error logging uses tracing::error!(error = ?e, ...), ensuring that error objects are never interpolated into log strings. When macro_env_var encounters a missing variable, it returns a VarNameErr that discards the raw value when formatted for logging (lines 176‑184 in crates/macro_env_var/src/lib.rs).

This approach guarantees that even if a secret is malformed or missing, its value never appears in log aggregation systems.

Zero-Trust Networking Architecture

Each microservice operates within a private VPC and exposes only the necessary HTTP endpoints. Internal adapters—such as those found in connection gateway services—use macro_env_var to retrieve AWS credentials without exposing them to the network. Access to internal APIs requires valid internal API keys, ensuring that services trust each other based on cryptographic identity rather than network location.

Summary

The security considerations for Macro Inc. demonstrate a comprehensive defense-in-depth strategy:

  • Secrets are never hard-coded, flowing exclusively through the audited macro_env_var crate
  • Compile-time validation catches missing configuration during builds, not deployments
  • JWT and internal API keys provide strong authentication for external users and internal services
  • SQLx compile-time query checks prevent injection attacks and schema mismatches
  • Logging discipline ensures sensitive values never appear in error traces
  • Static AWS keys are confined to CI, while production uses short-lived IAM credentials

Frequently Asked Questions

How does Macro Inc. prevent secrets from being hard-coded in the source code?

All secrets are loaded through the macro_env_var crate, which reads from the APP_SECRETS_JSON environment variable (managed by Doppler) or the process environment. The env_var! macro generates types that enforce loading at runtime or compile-time validation, ensuring that plaintext secrets never appear in source files or version control.

What mechanism ensures that required secrets are present before deployment?

The new_comptime() constructor on environment variable types forces a compile-time check. If a required secret is not present in the build environment, the Rust compiler fails immediately. This prevents the deployment of services with missing database credentials, JWT keys, or API tokens.

How do internal services authenticate with each other without exposing user credentials?

Internal services use signed internal API keys validated by the validate_internal_key function in macro_auth::internal_api_key. These keys are exchanged via HTTP headers and verified using secrets loaded through macro_env_var. Upon validation, the middleware injects a trusted UserId into the request context, allowing services to authorize actions without handling raw user passwords or session tokens.

What prevents SQL injection attacks in the Macro Inc. codebase?

The codebase exclusively uses SQLx macros like query! and query_as!, which validate SQL syntax and parameter types against the database schema at compile time. This approach eliminates string concatenation in queries and ensures that all user input is treated as bound parameters, effectively mitigating SQL injection risks.

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 →