lilydocs
HTTP APIWebSocketConsumer
Security2 min read

CORS

Control which origins, methods, and headers browsers can use to access your API.

CORS is the policy that lets a browser use a cross-origin response. It does not verify a user's identity or permission to perform an operation; those checks remain in guards.

Global policy#

Add the following snippet to the builder chain in your async startup function:

Rust
use std::time::Duration;
use lilyrs::http_api::{AppBuilder, CorsPolicy};

let policy = CorsPolicy::new()
    .allow_origins(["https://app.example.com"])
    .allow_methods(["GET", "POST", "PUT", "DELETE"])
    .allow_headers(["content-type", "authorization", "x-csrf-token"])
    .expose_headers(["x-request-id"])
    .allow_credentials(true)
    .max_age(Duration::from_secs(600));

let builder = AppBuilder::new("127.0.0.1:8080").cors(policy);

Then run the builder with build().await?.start().await?. Replace the origin list with your actual frontend addresses. When credentials are enabled, wildcard combinations for origins, methods, headers, and exposed headers are not allowed.

Controller and action policies#

Implement CorsPolicyProvider for a route-specific policy. Choose #[cors(Provider)] on the controller or action. Effective policy precedence is action → controller → global fallback.

CorsDisabled replaces the inherited policy with an empty/deny policy. It is not a bypass that disables the transport's CORS checks.

Dynamic origins#

Use resolve_origins_with::<Resolver>() to choose a type implementing CorsOriginResolver::new(Arc<Extensions>) and allows(&CorsOriginContext). Each resolver type is shared within the application; do not resolve Scoped services in its constructor. The context provides a view of request cancellation.

If origin lookup fails, do not fall back to unrestricted access. Apply your application's controlled rejection/error policy.

Preflight order#

A valid preflight can complete before general middleware and action guards. CORS does not grant access permissions; configure authentication and authorization requirements separately to protect your API.

Advanced options#

Global CORS is registered once. allow_private_network explicitly enables private network access, and allow_null_origin explicitly accepts a null origin. vary_by, max_age, and without_max_age configure response/cache policy. Enable them only for the access your application actually needs.

Sources for this page v0.1.0

This guide is based on the reviewed framework commit.

QUICK START
Documentation
Source code