Skip to content

Latest commit

 

History

History
502 lines (398 loc) · 20.2 KB

File metadata and controls

502 lines (398 loc) · 20.2 KB
page_title ory_project_config Resource - ory
subcategory
description Configures an Ory Network project's settings.

ory_project_config (Resource)

Configures an Ory Network project's settings.

This resource manages the configuration of an Ory Network project, including authentication methods, password policies, session settings, CORS, and more.

-> Plan: Available on all Ory Network plans. Some configuration options may require specific plan features.

This resource supports drift detection — terraform plan will detect changes made outside of Terraform (e.g., via Ory Console or API) for any attributes you have configured.

~> Note: Only attributes present in your Terraform configuration are tracked for drift. Attributes you have not configured will not appear in plan output, even if they have non-default values in the API.

Example Usage

# Basic project configuration
resource "ory_project_config" "basic" {
  cors_enabled        = true
  cors_origins        = ["https://app.example.com"]
  password_min_length = 10
  session_lifespan    = "720h0m0s" # 30 days
}

# Full security configuration
resource "ory_project_config" "secure" {
  # Public CORS
  cors_enabled = true
  cors_origins = ["https://app.example.com", "https://admin.example.com"]

  # Admin CORS
  cors_admin_enabled = true
  cors_admin_origins = ["https://admin.example.com"]

  # Sessions
  session_lifespan          = "168h0m0s" # 7 days
  session_cookie_same_site  = "Strict"
  session_cookie_persistent = true

  # Password Policy
  password_min_length            = 12
  password_identifier_similarity = true
  password_check_haveibeenpwned  = true
  password_max_breaches          = 0

  # Authentication Methods
  enable_password  = true
  enable_code      = true
  code_mfa_enabled = true # Enable code as a second factor for MFA
  enable_oidc      = true # Required for social providers (Google, GitHub, etc.)
  enable_passkey   = true

  # Flow Controls
  enable_registration = true
  enable_recovery     = true
  enable_verification = true

  # MFA
  enable_totp              = true
  totp_issuer              = "MyApp"
  enable_webauthn          = true
  webauthn_rp_display_name = "MyApp"
  webauthn_rp_id           = "app.example.com"
  webauthn_rp_origins      = ["https://app.example.com"]
  webauthn_passwordless    = true
  enable_lookup_secret     = true
  mfa_enforcement          = "optional"
  required_aal             = "aal1"

  # URLs
  default_return_url = "https://app.example.com/dashboard"
  allowed_return_urls = [
    "https://app.example.com/dashboard",
    "https://app.example.com/settings"
  ]

  # Account Experience Branding
  account_experience_name           = "MyApp"
  account_experience_logo_url       = "https://cdn.example.com/logo.png"
  account_experience_favicon_url    = "https://cdn.example.com/favicon.ico"
  account_experience_default_locale = "en"

  # OAuth2 Token Lifespans
  oauth2_access_token_lifespan          = "1h0m0s"
  oauth2_refresh_token_lifespan         = "720h0m0s"
  oauth2_auth_code_lifespan             = "30m0s"
  oauth2_id_token_lifespan              = "1h0m0s"
  oauth2_login_consent_request_lifespan = "30m0s"

  # OAuth2 Strategies
  oauth2_access_token_strategy = "jwt"
  oauth2_jwt_scope_claim       = "list"
  oauth2_scope_strategy        = "wildcard"

  # OAuth2 PKCE
  oauth2_pkce_enforced                    = false
  oauth2_pkce_enforced_for_public_clients = true

  # OAuth2 Claims
  oauth2_allowed_top_level_claims = ["amr", "acr"]
  oauth2_mirror_top_level_claims  = false

  # OAuth2 Issuer URL (custom issuer for OAuth2/OIDC tokens)
  oauth2_issuer_url = "https://auth.example.com"

  # OAuth2 Cookie Settings
  oauth2_cookies_same_site_mode              = "Strict"
  oauth2_cookies_same_site_legacy_workaround = false

  # Keto Namespaces (for fine-grained authorization)
  keto_namespaces = ["documents", "folders", "groups"]
}

# Login style controls how authentication methods are presented.
# Default is "unified" (all methods on one screen).
# Use "identifier_first" to collect the identifier before showing auth methods.
resource "ory_project_config" "identifier_first" {
  login_style     = "identifier_first"
  enable_password = true
  enable_code     = true
}

# Self-hosted UI configuration (custom login/registration pages)
resource "ory_project_config" "self_hosted_ui" {
  login_ui_url        = "https://auth.example.com/login"
  registration_ui_url = "https://auth.example.com/registration"
  recovery_ui_url     = "https://auth.example.com/recovery"
  verification_ui_url = "https://auth.example.com/verification"
  settings_ui_url     = "https://auth.example.com/settings"
  error_ui_url        = "https://auth.example.com/error"

  enable_password     = true
  enable_registration = true
  enable_recovery     = true
  enable_verification = true
}

# SMTP configuration for custom email delivery
resource "ory_project_config" "with_smtp" {
  smtp_connection_uri = var.smtp_connection_uri
  smtp_from_address   = "noreply@example.com"
  smtp_from_name      = "MyApp"
  smtp_headers = {
    "X-SES-CONFIGURATION-SET" = "my-config-set"
  }

  enable_password = true
}

variable "smtp_connection_uri" {
  type        = string
  sensitive   = true
  description = "SMTP connection URI (e.g., smtps://user:pass@smtp.example.com:465)"
}

# Native-only flows: explicitly clear browser return URLs
# Useful when the project only supports native (mobile/CLI) login flows
# and should not have any browser redirect URLs configured.
resource "ory_project_config" "native_only" {
  default_return_url  = ""
  allowed_return_urls = []

  enable_password = true
  enable_code     = true
}

# Session tokenizer templates (JWT tokenization for /sessions/whoami)
resource "ory_project_config" "with_tokenizer" {
  session_tokenizer_templates = {
    my_jwt = {
      ttl               = "1h"
      jwks_url          = "base64://eyJrZXlzIjpbXX0="
      claims_mapper_url = "base64://bG9jYWwgcGF5bG9hZCA9IHN0ZC5leHRWYXIoJ3BheWxvYWQnLCB7fSk7CnsKICBzZXNzaW9uX2lkOiBwYXlsb2FkLnNlc3Npb24uaWQsCn0="
      subject_source    = "id"
    }
    short_lived = {
      ttl      = "5m"
      jwks_url = "base64://eyJrZXlzIjpbXX0="
    }
  }
}

# Courier HTTP delivery (webhook-based email/SMS delivery)
resource "ory_project_config" "with_courier_http" {
  courier_delivery_strategy = "http"

  courier_http_request_config = {
    url    = "https://mail-api.example.com/send"
    method = "POST"
    body   = "base64://ewogICJyZWNpcGllbnQiOiAge3sgLnJlY2lwaWVudCB9fSwKICAiYm9keSI6IHt7IC5ib2R5IH19Cn0="
    auth = {
      type     = "basic_auth"
      user     = "mailuser"
      password = var.mail_password
    }
  }

  # Per-channel delivery (e.g., SMS via Twilio)
  courier_channels = [
    {
      id = "sms"
      request_config = {
        url    = "https://sms-api.example.com/send"
        method = "POST"
        body   = "base64://ewogICJ0byI6IHt7IC5yZWNpcGllbnQgfX0sCiAgIm1lc3NhZ2UiOiB7eyAuYm9keSB9fQp9"
        auth = {
          type  = "api_key"
          name  = "Authorization"
          value = var.sms_api_key
          in    = "header"
        }
      }
    }
  ]
}

variable "mail_password" {
  type        = string
  sensitive   = true
  description = "Password for courier HTTP basic auth"
}

variable "sms_api_key" {
  type        = string
  sensitive   = true
  description = "API key for SMS delivery service"
}

Duration Format

Time-based attributes use Go duration strings. Examples:

Duration Meaning
30m 30 minutes
1h 1 hour
24h0m0s 24 hours
168h 7 days
720h 30 days
8760h 365 days

Import

Import using the project ID:

terraform import ory_project_config.main <project-id>

Avoiding "Forces Replacement" After Import

After importing, if Terraform shows project_id forces replacement, ensure your configuration matches:

Option 1: Explicit project_id

resource "ory_project_config" "main" {
  project_id = "the-exact-project-id-you-imported"
  # ... other settings
}

Option 2: Use provider default (recommended)

provider "ory" {
  project_id = "the-exact-project-id-you-imported"
}

resource "ory_project_config" "main" {
  # project_id inherits from provider
  # ... other settings
}

CORS Configuration

This resource supports CORS configuration for both public and admin endpoints:

  • Public CORS (cors_enabled, cors_origins) — Controls CORS for public-facing endpoints (login, registration, etc.)
  • Admin CORS (cors_admin_enabled, cors_admin_origins) — Controls CORS for admin API endpoints

Clearing Return URLs

To explicitly clear default_return_url and allowed_return_urls (e.g., for native-only flows with no browser redirects), set them to empty values:

resource "ory_project_config" "native_only" {
  default_return_url  = ""
  allowed_return_urls = []
}

Omitting these attributes entirely (or setting them to null) leaves the existing API values unchanged.

Notes

  • Project config cannot be deleted — it always exists for a project
  • Deleting this resource from Terraform state does not reset the project configuration
  • The project_id attribute forces replacement if changed (you cannot move config to a different project)
  • After terraform import, run terraform plan to reconcile your configuration with the current API state

Coverage and Limitations

This resource exposes 75+ attributes across these configuration categories:

Category Examples
Password settings min length, identifier similarity, max breaches, haveibeenpwned
Session settings cookie same site, lifespan, whoami-required AAL
CORS public and admin origins, enabled/disabled
Login flow login style (unified, identifier_first)
Authentication passwordless, code, OIDC (social sign-in), TOTP, passkey, WebAuthn, lookup secrets
OAuth2/Hydra token lifespans, access token strategy, PKCE, claims, scope strategy, consent/login URLs
Recovery / Verification enabled, methods, notify unknown recipients
Account enumeration mitigation enabled
Keto namespace configuration

Not Yet Exposed

Some Ory project settings are not yet available through this resource. For settings not listed above, use one of these workarounds:

  • Ory Consoleconsole.ory.sh
  • Ory CLIory patch project --replace '/services/identity/config/...'
  • APIPATCH /projects/{project_id} with JSON Patch operations

Schema

Optional

  • account_experience_default_locale (String) Default locale for the hosted login UI (e.g., 'en', 'de').
  • account_experience_favicon_url (String) URL for the favicon in the hosted login UI.
  • account_experience_logo_url (String) URL for the logo in the hosted login UI.
  • account_experience_name (String) Application name shown in the hosted login UI.
  • account_experience_stylesheet (String) Custom CSS stylesheet for the hosted login UI.
  • allowed_return_urls (List of String) List of allowed return URLs.
  • code_mfa_enabled (Boolean) Enable the code method as a second factor for MFA. When enabled, users can use one-time codes as a second authentication factor.
  • cors_admin_enabled (Boolean) Enable CORS for the admin API.
  • cors_admin_origins (List of String) Allowed CORS origins for the admin API.
  • cors_enabled (Boolean) Enable CORS for the public API.
  • cors_origins (List of String) Allowed CORS origins.
  • courier_channels (Attributes List) Per-channel courier delivery configurations (e.g., SMS via Twilio). Each channel overrides the default delivery for a specific message channel. (see below for nested schema)
  • courier_delivery_strategy (String) Courier delivery strategy: 'smtp' (default) or 'http'.
  • courier_http_request_config (Attributes) HTTP request configuration for courier message delivery (used when courier_delivery_strategy is 'http'). (see below for nested schema)
  • default_return_url (String) Default URL to redirect after flows.
  • enable_code (Boolean) Enable code-based authentication.
  • enable_lookup_secret (Boolean) Enable backup/recovery codes.
  • enable_oidc (Boolean) Enable OIDC (OpenID Connect) social sign-in. Must be enabled for social providers (e.g. Google, GitHub) to work.
  • enable_passkey (Boolean) Enable Passkey authentication.
  • enable_password (Boolean) Enable password authentication.
  • enable_recovery (Boolean) Enable password recovery flow.
  • enable_registration (Boolean) Enable user registration.
  • enable_totp (Boolean) Enable TOTP (Time-based One-Time Password).
  • enable_verification (Boolean) Enable email verification flow.
  • enable_webauthn (Boolean) Enable WebAuthn (hardware keys).
  • error_ui_url (String) URL for the error UI.
  • keto_namespaces (List of String) List of Keto namespace names to configure for Ory Permissions. Namespaces define the types of resources in your permission model (e.g., 'documents', 'folders'). Each namespace name must be unique.
  • login_style (String) Login flow style: 'unified' (default) shows all auth methods on one screen, 'identifier_first' collects the identifier before showing auth methods.
  • login_ui_url (String) URL for the login UI.
  • mfa_enforcement (String) MFA enforcement level: 'none', 'optional', or 'required'.
  • oauth2_access_token_lifespan (String) OAuth2 access token lifespan (e.g., '1h', '30m'). Requires Hydra service.
  • oauth2_access_token_strategy (String) OAuth2 access token strategy ('jwt' or 'opaque').
  • oauth2_allowed_top_level_claims (List of String) List of allowed top-level claims in OAuth2 access tokens (e.g., 'amr', 'acr').
  • oauth2_auth_code_lifespan (String) OAuth2 authorization code lifespan (e.g., '30m'). Requires Hydra service.
  • oauth2_consent_url (String) OAuth2 consent endpoint URL.
  • oauth2_cookies_same_site_legacy_workaround (Boolean) Enable the SameSite=None legacy workaround for OAuth2 cookies. When enabled, a fallback cookie without SameSite is set alongside the main cookie for clients that don't support SameSite=None.
  • oauth2_cookies_same_site_mode (String) SameSite attribute for OAuth2 cookies ('Lax', 'Strict', 'None').
  • oauth2_error_url (String) OAuth2 error endpoint URL.
  • oauth2_id_token_lifespan (String) OAuth2 ID token lifespan (e.g., '1h'). Requires Hydra service.
  • oauth2_issuer_url (String) OAuth2 issuer URL. Overrides the default project URL used as the OAuth2/OIDC issuer.
  • oauth2_jwt_scope_claim (String) How scopes are represented in JWT access tokens ('list', 'string', or 'both').
  • oauth2_login_consent_request_lifespan (String) OAuth2 login/consent request lifespan (e.g., '30m'). Requires Hydra service.
  • oauth2_login_url (String) OAuth2 login endpoint URL.
  • oauth2_logout_url (String) OAuth2 logout endpoint URL.
  • oauth2_mirror_top_level_claims (Boolean) Mirror top-level claims in OAuth2 ID tokens.
  • oauth2_pkce_enforced (Boolean) Enforce PKCE for all OAuth2 clients.
  • oauth2_pkce_enforced_for_public_clients (Boolean) Enforce PKCE for public OAuth2 clients only.
  • oauth2_refresh_token_lifespan (String) OAuth2 refresh token lifespan (e.g., '720h' for 30 days). Requires Hydra service.
  • oauth2_scope_strategy (String) OAuth2 scope matching strategy ('exact', 'wildcard').
  • oauth2_session_encrypt_at_rest (Boolean) Encrypt OAuth2 sessions at rest.
  • password_check_haveibeenpwned (Boolean) Check passwords against HaveIBeenPwned.
  • password_identifier_similarity (Boolean) Check password similarity to identifier.
  • password_max_breaches (Number) Maximum allowed breaches in HaveIBeenPwned.
  • password_min_length (Number) Minimum password length.
  • project_id (String) Project ID to configure. If not set, uses provider's project_id.
  • recovery_ui_url (String) URL for the password recovery UI.
  • registration_ui_url (String) URL for the registration UI.
  • required_aal (String) Required Authenticator Assurance Level for protected resources: 'aal1' or 'aal2'.
  • session_cookie_persistent (Boolean) Enable persistent session cookies (survive browser close).
  • session_cookie_same_site (String) SameSite cookie attribute (Lax, Strict, None).
  • session_lifespan (String) Session duration (e.g., '24h0m0s').
  • session_tokenizer_templates (Attributes Map) JWT tokenizer templates for the /sessions/whoami endpoint. Each key is a template name, and the value configures how JWTs are generated. (see below for nested schema)
  • session_whoami_required_aal (String) Required AAL for session whoami endpoint: 'aal1', 'aal2', or 'highest_available'.
  • settings_ui_url (String) URL for the account settings UI.
  • smtp_connection_uri (String, Sensitive) SMTP connection URI for sending emails.
  • smtp_from_address (String) Email address to send from.
  • smtp_from_name (String) Name to display as sender.
  • smtp_headers (Map of String) Custom headers to include in emails.
  • totp_issuer (String) TOTP issuer name shown in authenticator apps.
  • verification_ui_url (String) URL for the verification UI.
  • webauthn_passwordless (Boolean) Enable passwordless WebAuthn authentication.
  • webauthn_rp_display_name (String) WebAuthn Relying Party display name.
  • webauthn_rp_id (String) WebAuthn Relying Party ID (typically your domain).
  • webauthn_rp_origins (List of String) Allowed WebAuthn origins.

Read-Only

  • id (String) Resource ID (same as project_id).

Nested Schema for courier_channels

Required:

  • id (String) Channel identifier (e.g., 'sms').

Optional:

Nested Schema for courier_channels.request_config

Required:

  • method (String) HTTP method (e.g., 'POST', 'PUT').
  • url (String) Target URL for the HTTP request.

Optional:

  • auth (Attributes) Authentication configuration for the HTTP request. (see below for nested schema)
  • body (String) Request body template. Supports base64:// scheme for Jsonnet templates.
  • headers (Map of String) Additional HTTP headers to include.

Nested Schema for courier_channels.request_config.auth

Required:

  • type (String) Authentication type: 'basic_auth' or 'api_key'.

Optional:

  • in (String) Where to send the API key: 'header', 'cookie', or 'query'.
  • name (String) Header/cookie/query parameter name for api_key auth.
  • password (String, Sensitive) Password for basic_auth.
  • user (String) Username for basic_auth.
  • value (String, Sensitive) API key value for api_key auth.

Nested Schema for courier_http_request_config

Required:

  • method (String) HTTP method (e.g., 'POST', 'PUT').
  • url (String) Target URL for the HTTP request.

Optional:

  • auth (Attributes) Authentication configuration for the HTTP request. (see below for nested schema)
  • body (String) Request body template. Supports base64:// scheme for Jsonnet templates.
  • headers (Map of String) Additional HTTP headers to include.

Nested Schema for courier_http_request_config.auth

Required:

  • type (String) Authentication type: 'basic_auth' or 'api_key'.

Optional:

  • in (String) Where to send the API key: 'header', 'cookie', or 'query'.
  • name (String) Header/cookie/query parameter name for api_key auth.
  • password (String, Sensitive) Password for basic_auth.
  • user (String) Username for basic_auth.
  • value (String, Sensitive) API key value for api_key auth.

Nested Schema for session_tokenizer_templates

Required:

  • jwks_url (String, Sensitive) JWKS URL for signing tokens. Must use base64:// scheme (e.g., 'base64://eyJrZXlzIjpbXX0=').

Optional:

  • claims_mapper_url (String) Jsonnet claims mapper URL. Supports base64:// and https:// schemes.
  • subject_source (String) Subject source for the JWT: 'id' (default) or 'external_id'.
  • ttl (String) Token time-to-live duration (e.g., '1h', '30m'). Default: '1m'.