# Copyright 2021 Collate # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # http://www.apache.org/licenses/LICENSE-2.0 # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. clusterName: ${OPENMETADATA_CLUSTER_NAME:-openmetadata} swagger: resourcePackage: org.openmetadata.service.resources assets: resourcePath: /assets/ uriPath: / basePath: ${BASE_PATH:-/} server: applicationContextPath: ${BASE_PATH:-/} rootPath: /api/* applicationConnectors: # # Connector protocol. Two supported values: # # - http (default): HTTP/1.1 only. Compatible with every load balancer and proxy # ever shipped. Pick this if you front Jetty with an HTTP/2-terminating LB # (AWS ALB / CloudFront / nginx / Caddy) — those speak HTTP/2 to the browser # but downgrade to HTTP/1.1 on the upstream hop anyway, so HTTP/2 on Jetty # buys nothing. # # - h2c HTTP/2 cleartext on the same TCP port. Jetty 12 accepts both h1 clients # (via h1 protocol) and h2 clients (via h2c-upgrade or h2c-prior-knowledge), # so this is backwards-compatible. Worth flipping on when browsers hit Jetty # directly (Docker Compose, on-prem single-node, local dev) — multiplexing # removes the h1 6-connections-per-origin cap, which materially helps cold # first-paint on SPAs that load 30+ chunks. # # For HTTPS-terminated HTTP/2 (`type: h2`) see the example block lower in this file — # that path requires a keystore and isn't env-var-driven from here. # # Requires the dropwizard-http2 module (already pulled in by openmetadata-service). - type: ${SERVER_PROTOCOL:-http} bindHost: ${SERVER_HOST:-0.0.0.0} port: ${SERVER_PORT:-8585} # Jetty 12 URI Compliance - UNSAFE allows all special characters in entity names # Required for backward compatibility with entity names containing /, ", etc. uriCompliance: UNSAFE # Jetty Acceptor and Selector threads for high concurrency acceptorThreads: ${SERVER_ACCEPTOR_THREADS:-2} # 1-2 per CPU core selectorThreads: ${SERVER_SELECTOR_THREADS:-8} # 2-4 per CPU core # Connection settings - relaxed for Docker/local development acceptQueueSize: ${SERVER_ACCEPT_QUEUE_SIZE:-256} # OS-level connection backlog idleTimeout: ${SERVER_IDLE_TIMEOUT:-60 seconds} # Close idle connections (increased from 30s) # Buffer sizes for better throughput outputBufferSize: ${SERVER_OUTPUT_BUFFER_SIZE:-32KiB} inputBufferSize: ${SERVER_INPUT_BUFFER_SIZE:-8KiB} maxRequestHeaderSize: ${SERVER_MAX_REQUEST_HEADER_SIZE:-8KiB} maxResponseHeaderSize: ${SERVER_MAX_RESPONSE_HEADER_SIZE:-8KiB} headerCacheSize: ${SERVER_HEADER_CACHE_SIZE:-512B} # Cache parsed headers (in bytes) # Performance settings useServerHeader: false # Don't send server version header useDateHeader: true useForwardedHeaders: ${SERVER_USE_FORWARDED_HEADERS:-false} # Enable if behind proxy # Data rate limits (prevent slow loris attacks) minRequestDataPerSecond: ${SERVER_MIN_REQUEST_DATA_RATE:-0B} # 0B = disabled minResponseDataPerSecond: ${SERVER_MIN_RESPONSE_DATA_RATE:-0B} # 0B = disabled adminConnectors: - type: http bindHost: ${SERVER_HOST:-0.0.0.0} port: ${SERVER_ADMIN_PORT:-8586} acceptorThreads: 1 # Admin endpoint needs minimal resources selectorThreads: 1 # Response compression for entity GETs / list endpoints — Dropwizard delegates to Jetty's # GzipHandler. Default min size is ~256 bytes; below that the CPU cost outweighs the wire # savings. Pre-compressed UI assets (.gz / .br produced at vite build time) are served by # OpenMetadataAssetServlet's content negotiation, not by this handler. gzip: enabled: true # Thread pool configuration # With virtual threads enabled (Java 21+), these settings become less critical # as blocking operations are handled efficiently by the JVM maxThreads: ${SERVER_MAX_THREADS:-150} minThreads: ${SERVER_MIN_THREADS:-100} idleThreadTimeout: ${SERVER_IDLE_THREAD_TIMEOUT:-1 minute} # Virtual Threads (Project Loom) - Recommended for Java 21+ # Jetty 12 uses AdaptiveExecutionStrategy to route blocking tasks to virtual threads # while keeping non-blocking I/O on platform threads for optimal cache locality enableVirtualThreads: ${SERVER_ENABLE_VIRTUAL_THREAD:-false} # Note: maxQueuedRequests removed in Dropwizard 5.0/Jetty 12 # Request/Response logging (disable in production for performance) # Set LOG_FORMAT=json for structured logs. The default text format preserves legacy output. requestLog: appenders: - type: console threshold: ${REQUEST_LOG_LEVEL:-ERROR} # Only log errors by default layout: type: om-access-layout format: ${LOG_FORMAT:-text} appendLineSeparator: true # Above configuration for running http is fine for dev and testing. # For production setup, where UI app will hit apis through DPS it # is strongly recommended to run https instead. Note that only # keyStorePath and keyStorePassword are mandatory properties. Values # for other properties are defaults #server: #applicationConnectors: # - type: https # port: 8585 # keyStorePath: ./conf/keystore.jks # keyStorePassword: changeit # keyStoreType: JKS # keyStoreProvider: # trustStorePath: /path/to/file # trustStorePassword: changeit # trustStoreType: JKS # trustStoreProvider: # keyManagerPassword: changeit # needClientAuth: false # wantClientAuth: # certAlias: # crlPath: /path/to/file # enableCRLDP: false # enableOCSP: false # maxCertPathLength: (unlimited) # ocspResponderUrl: (none) # jceProvider: (none) # validateCerts: true # validatePeers: true # supportedProtocols: [TLSv1.2, TLSv1.3] # supportedCipherSuites: [TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] # allowRenegotiation: true # endpointIdentificationAlgorithm: (none) #adminConnectors: # - type: https # port: 8586 # keyStorePath: ./conf/keystore.jks # keyStorePassword: changeit # keyStoreType: JKS # keyStoreProvider: # trustStorePath: /path/to/file # trustStorePassword: changeit # trustStoreType: JKS # trustStoreProvider: # keyManagerPassword: changeit # needClientAuth: false # wantClientAuth: # certAlias: # crlPath: /path/to/file # enableCRLDP: false # enableOCSP: false # maxCertPathLength: (unlimited) # ocspResponderUrl: (none) # jceProvider: (none) # validateCerts: true # validatePeers: true # supportedProtocols: [TLSv1.2, TLSv1.3] # supportedCipherSuites: [TLS_AES_256_GCM_SHA384, TLS_AES_128_GCM_SHA256, TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256] # allowRenegotiation: true # endpointIdentificationAlgorithm: (none) # HTTP/2 support — opt-in. The dropwizard-http2 module is on the classpath, so the # `type: h2` (TLS) and `type: h2c` (cleartext) connector types are available out of the # box. Both are backward-compatible: HTTP/1.1 clients still work on the same port (h2c # negotiates via the HTTP/1.1 Upgrade header; h2 negotiates via TLS ALPN), so flipping # from `type: http` to `type: h2c` does not break the SDK or browser. # # When to enable at Jetty: # * Self-hosted single-node deploys with no LB in front (Jetty IS the edge). # * Production deploys that want end-to-end HTTP/2 — multiplexing all the way through # instead of LB↔pod fanning out to many HTTP/1.1 connections under high parallelism. # * Behind h2c-aware proxies (envoy, nginx with `proxy_http_version 2`). # # When to leave HTTP/2 to the LB and keep `type: http` here: # * Production deploys behind nginx-ingress / ALB / Traefik that already terminate # HTTP/2 from clients. The LB↔pod hop in HTTP/1.1 is "fine" intra-VPC, and not # worth the cert-management cost for marginal multiplexing gains. # # HTTP/2 cleartext (h2c) on the existing port — most common opt-in shape: #server: # applicationConnectors: # - type: h2c # port: 8585 # maxConcurrentStreams: 1024 # initialStreamRecvWindow: 65535 # adminConnectors: # - type: http # admin endpoint stays HTTP/1.1; ops scrapers don't need HTTP/2 # port: 8586 # # HTTP/2 over TLS (h2) for browser-direct deploys — replaces the https sample above: #server: # applicationConnectors: # - type: h2 # port: 8585 # keyStorePath: ./conf/keystore.jks # keyStorePassword: changeit # keyStoreType: JKS # supportedProtocols: [TLSv1.2, TLSv1.3] # # h2 mandates the cipher list include AEAD suites (RFC 7540 §9.2.2): # supportedCipherSuites: # - TLS_AES_256_GCM_SHA384 # - TLS_AES_128_GCM_SHA256 # - TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 # - TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256 qos: # Virtual threads remove Jetty's natural back-pressure. Keep request admission below the DB # pool ceiling so excess load queues instead of failing with connection exhaustion. enabled: ${QOS_ENABLED:-true} maxRequestCount: ${QOS_MAX_REQUEST_COUNT:-64} maxSuspendedRequestCount: ${QOS_MAX_SUSPENDED_REQUEST_COUNT:-1000} maxSuspendSeconds: ${QOS_MAX_SUSPEND_SECONDS:-30} cacheMemory: # Entity JSON caches (CACHE_WITH_ID, CACHE_WITH_NAME) — weight-based eviction. # Entity JSON can range from 1KB to 2MB+. Increase on high-memory deployments for better hit rates. entityCacheMaxSizeBytes: ${ENTITY_CACHE_MAX_SIZE_BYTES:-104857600} # 100 MB entityCacheTTLSeconds: ${ENTITY_CACHE_TTL_SECONDS:-30} # Auth caches (user context + policies) — TTLs hardcoded (2min policies, 15min user context) authCacheMaxEntries: ${AUTH_CACHE_MAX_ENTRIES:-5000} # RBAC query cache (OpenSearch role-based access control query DSL) rbacCacheMaxEntries: ${RBAC_CACHE_MAX_ENTRIES:-5000} # Logging settings. # https://logback.qos.ch/manual/layouts.html#conversionWord # Set LOG_FORMAT=json for structured logs. The default text format preserves legacy output. logging: level: ${LOG_LEVEL:-INFO} loggers: org.openmetadata.service.util.jdbi.OMSqlLogger: level: ${SQL_LOG_LEVEL:-INFO} additive: false appenders: - type: file layout: type: om-event-layout format: ${LOG_FORMAT:-text} pattern: "%level [%d{ISO8601,UTC}] [%t] %logger{5} - %msg%n" appendLineSeparator: true threshold: DEBUG currentLogFilename: ./logs/queries.log archivedLogFilenamePattern: ./logs/queries-%d{yyyy-MM-dd}-%i.log.gz archivedFileCount: 7 timeZone: UTC maxFileSize: 50MB org.openmetadata.service.util.OpenMetadataSetup: level: INFO appenders: - type: console timeZone: UTC layout: type: om-event-layout format: ${LOG_FORMAT:-text} pattern: "%msg%n" appendLineSeparator: true - type: file layout: type: om-event-layout format: ${LOG_FORMAT:-text} pattern: "%level [%d{ISO8601,UTC}] [%t] %logger{5} - %msg%n" currentLogFilename: ./logs/openmetadata-operations.log archivedLogFilenamePattern: ./logs/openmetadata-operations-%d{yyyy-MM-dd}-%i.log.gz archivedFileCount: 7 timeZone: UTC maxFileSize: 50MB org.openmetadata.service.audit.AuditLogRepository: # Audit entries are logged at INFO with the AUDIT marker (see AuditLogger) and routed to # logs/audit.log. Pin the level so audit capture does not depend on the global LOG_LEVEL. level: INFO appenders: - type: console threshold: TRACE timeZone: UTC layout: type: om-event-layout format: ${LOG_FORMAT:-text} pattern: "%level [%d{ISO8601,UTC}] [%t] %logger{5} - %msg%n" appendLineSeparator: true filterFactories: - type: audit-exclude-filter-factory - type: file layout: type: om-event-layout format: ${LOG_FORMAT:-text} pattern: "%level [%d{ISO8601,UTC}] [%t] %logger{5} - %msg%n" appendLineSeparator: true filterFactories: - type: audit-exclude-filter-factory threshold: TRACE currentLogFilename: ./logs/openmetadata.log archivedLogFilenamePattern: ./logs/openmetadata-%d{yyyy-MM-dd}-%i.log.gz archivedFileCount: 7 timeZone: UTC maxFileSize: 50MB - type: file layout: type: om-event-layout format: ${LOG_FORMAT:-text} pattern: "%level [%d{ISO8601,UTC}] [%t] %logger{5} - %msg%n" appendLineSeparator: true filterFactories: - type: audit-only-filter-factory threshold: TRACE currentLogFilename: ./logs/audit.log archivedLogFilenamePattern: ./logs/audit-%d{yyyy-MM-dd}-%i.log.gz archivedFileCount: 25 timeZone: UTC maxFileSize: 50MB database: # the name of the JDBC driver, mysql in our case driverClass: ${DB_DRIVER_CLASS:-com.mysql.cj.jdbc.Driver} # the username and password user: ${DB_USER:-openmetadata_user} password: ${DB_USER_PASSWORD:-openmetadata_password} # the JDBC URL; the database is called openmetadata_db url: jdbc:${DB_SCHEME:-mysql}://${DB_HOST:-localhost}:${DB_PORT:-3306}/${OM_DATABASE:-openmetadata_db}?${DB_PARAMS:-allowPublicKeyRetrieval=true&useSSL=false&serverTimezone=UTC} # HikariCP Connection Pool Settings - Optimized for Performance maxSize: ${DB_CONNECTION_POOL_MAX_SIZE:-100} # Increased from 50 for better concurrency minSize: ${DB_CONNECTION_POOL_MIN_SIZE:-20} # Increased from 10 to reduce connection creation overhead minimumIdle: ${DB_CONNECTION_POOL_MIN_IDLE:-20} # HikariCP specific minimum idle connections initialSize: ${DB_CONNECTION_POOL_INITIAL_SIZE:-20} # Start with more connections ready checkConnectionWhileIdle: ${DB_CONNECTION_CHECK_CONNECTION_WHILE_IDLE:-true} checkConnectionOnBorrow: ${DB_CONNECTION_CHECK_CONNECTION_ON_BORROW:-false} # Disable for performance evictionInterval: ${DB_CONNECTION_EVICTION_INTERVAL:-5 minutes} minIdleTime: ${DB_CONNECTION_MIN_IDLE_TIME:-5 minute} # JDBC Driver Properties - Critical for Performance # These work across both PostgreSQL and MySQL drivers properties: # HikariCP connection pool settings connectionTimeout: ${DB_CONNECTION_TIMEOUT:-30000} # 30 seconds - fail fast if pool exhausted idleTimeout: ${DB_IDLE_TIMEOUT:-120000} # 2 minutes - reclaim idle connections faster maxLifetime: ${DB_MAX_LIFETIME:-600000} # 10 minutes - rotate connections (cloud DB friendly) leakDetectionThreshold: ${DB_LEAK_DETECTION_THRESHOLD:-60000} # 1 minute - detect leaks early keepaliveTime: ${DB_KEEPALIVE_TIME:-0} # 0 = disabled (set to 30000 for Aurora) validationTimeout: ${DB_VALIDATION_TIMEOUT:-5000} # 5 seconds - HikariCP default # PostgreSQL specific - these are ignored by MySQL driver prepareThreshold: ${DB_PG_PREPARE_THRESHOLD:-1} # Use prepared statements immediately preparedStatementCacheQueries: ${DB_PG_PREP_STMT_CACHE_QUERIES:-500} # Cache more statements preparedStatementCacheSizeMiB: ${DB_PG_PREP_STMT_CACHE_SIZE_MB:-10} # Larger cache reWriteBatchedInserts: ${DB_PG_REWRITE_BATCHED_INSERTS:-true} # Critical for batch performance defaultRowFetchSize: ${DB_PG_DEFAULT_ROW_FETCH_SIZE:-1000} # Fetch more rows at once assumeMinServerVersion: ${DB_PG_ASSUME_MIN_SERVER_VERSION:-12} # Skip version checks ApplicationName: ${DB_PG_APPLICATION_NAME:-OpenMetadata} loginTimeout: ${DB_PG_LOGIN_TIMEOUT:-300} # Login timeout in seconds postgresqlConnectTimeout: ${DB_POSTGRESQL_CONNECT_TIMEOUT:-60} # Connection timeout in seconds postgresqlSocketTimeout: ${DB_POSTGRESQL_SOCKET_TIMEOUT:-30000} # Socket timeout in seconds (0 = infinite) # Aurora PostgreSQL specific optimizations loadBalanceHosts: ${DB_PG_LOAD_BALANCE_HOSTS:-false} # Set to true for Aurora reader endpoints hostRecheckSeconds: ${DB_PG_HOST_RECHECK_SECONDS:-10} # How often to check host status targetServerType: ${DB_PG_TARGET_SERVER_TYPE:-primary} # primary, secondary, any, preferSecondary # MySQL specific - these are ignored by PostgreSQL driver rewriteBatchedStatements: ${DB_MYSQL_REWRITE_BATCHED_STATEMENTS:-true} # Critical for MySQL batch cachePrepStmts: ${DB_MYSQL_CACHE_PREP_STMTS:-true} prepStmtCacheSize: ${DB_MYSQL_PREP_STMT_CACHE_SIZE:-500} prepStmtCacheSqlLimit: ${DB_MYSQL_PREP_STMT_CACHE_SQL_LIMIT:-2048} useServerPrepStmts: ${DB_MYSQL_USE_SERVER_PREP_STMTS:-true} useLocalSessionState: ${DB_MYSQL_USE_LOCAL_SESSION_STATE:-true} useLocalTransactionState: ${DB_MYSQL_USE_LOCAL_TRANSACTION_STATE:-true} elideSetAutoCommits: ${DB_MYSQL_ELIDE_SET_AUTO_COMMITS:-true} maintainTimeStats: ${DB_MYSQL_MAINTAIN_TIME_STATS:-false} cacheResultSetMetadata: ${DB_MYSQL_CACHE_RESULT_SET_METADATA:-true} cacheServerConfiguration: ${DB_MYSQL_CACHE_SERVER_CONFIG:-true} tcpKeepAlive: ${DB_MYSQL_TCP_KEEP_ALIVE:-true} tcpNoDelay: ${DB_MYSQL_TCP_NO_DELAY:-true} mysqlConnectTimeout: ${DB_MYSQL_CONNECT_TIMEOUT:-60000} # Connection timeout in milliseconds mysqlSocketTimeout: ${DB_MYSQL_SOCKET_TIMEOUT:-30000000} # Socket timeout in milliseconds (0 = infinite) objectStorage: enabled: ${ASSET_UPLOADER_ENABLE:-false} # options: "s3", "azure", or "inmemory" (local testing, non-persistent). # For MinIO use provider "s3" and point s3.endpoint at the MinIO server. provider: ${ASSET_UPLOADER_PROVIDER:-s3} maxFileSize: ${ASSET_UPLOADER_MAX_FILE_SIZE:-5242880} s3: endpoint: ${ASSET_UPLOADER_S3_ENDPOINT:-""} bucketName: ${ASSET_UPLOADER_S3_BUCKET_NAME:-"my-bucket"} region: ${ASSET_UPLOADER_S3_REGION:-"us-east-2"} accessKey: ${ASSET_UPLOADER_S3_ACCESS_KEY:-"minio"} secretKey: ${ASSET_UPLOADER_S3_SECRET_KEY:-"minio123"} useIamRole: ${ASSET_UPLOADER_S3_USE_IAM_ROLE:-false} iamRoleArn: ${ASSET_UPLOADER_S3_IAM_ROLE_ARN:-""} prefixPath: ${ASSET_UPLOADER_S3_PREFIX_PATH:-"default"} sseAlgorithm: ${ASSET_UPLOADER_S3_SSE_ALGORITHM:-""} # Allowed values: "AES256" or "aws:kms" kmsKeyId: ${ASSET_UPLOADER_S3_KMS_KEY_ID:-""} # Required only if sseAlgorithm is "aws:kms" azure: containerName: ${ASSET_UPLOADER_AZURE_CONTAINER_NAME:-"my-container"} connectionString: ${ASSET_UPLOADER_AZURE_CONNECTION_STRING:-""} useManagedIdentity: ${ASSET_UPLOADER_AZURE_USE_MANAGED_IDENTITY:-false} clientId: ${ASSET_UPLOADER_AZURE_CLIENT_ID:-"clientId"} tenantId: ${ASSET_UPLOADER_AZURE_TENANT_ID:-"tenantId"} clientSecret: ${ASSET_UPLOADER_AZURE_CLIENT_SECRET:-"clientSecret"} blobEndpoint: ${ASSET_UPLOADER_AZURE_BLOB_ENDPOINT:-""} prefixPath: ${ASSET_UPLOADER_AZURE_PREFIX_PATH:-"assets/default"} migrationConfiguration: flywayPath: "./bootstrap/sql/migrations/flyway" nativePath: "./bootstrap/sql/migrations/native" extensionPath: "" # Authorizer Configuration authorizerConfiguration: className: ${AUTHORIZER_CLASS_NAME:-org.openmetadata.service.security.DefaultAuthorizer} containerRequestFilter: ${AUTHORIZER_REQUEST_FILTER:-org.openmetadata.service.security.JwtFilter} adminPrincipals: ${AUTHORIZER_ADMIN_PRINCIPALS:-[admin]} # For MCP OAuth: Set to specific domains like ["company.com"] to restrict self-signup allowedEmailRegistrationDomains: ${AUTHORIZER_ALLOWED_REGISTRATION_DOMAIN:-["all"]} principalDomain: ${AUTHORIZER_PRINCIPAL_DOMAIN:-"open-metadata.org"} allowedDomains: ${AUTHORIZER_ALLOWED_DOMAINS:-[]} enforcePrincipalDomain: ${AUTHORIZER_ENFORCE_PRINCIPAL_DOMAIN:-false} enableSecureSocketConnection : ${AUTHORIZER_ENABLE_SECURE_SOCKET:-false} useRolesFromProvider: ${AUTHORIZER_USE_ROLES_FROM_PROVIDER:-false} # For MCP OAuth: Default role assigned to new OAuth users (e.g., "DataConsumer") defaultOAuthRole: ${AUTHORIZER_DEFAULT_OAUTH_ROLE:-null} authenticationConfiguration: # For SSO: Set to "confidential" and configure OIDC settings below clientType: ${AUTHENTICATION_CLIENT_TYPE:-public} # For SSO: Set to "google", "okta", "azure", etc. and configure OIDC credentials provider: ${AUTHENTICATION_PROVIDER:-basic} # This is used by auth provider provide response as either id_token or code responseType: ${AUTHENTICATION_RESPONSE_TYPE:-id_token} # This will only be valid when provider type specified is customOidc providerName: ${CUSTOM_OIDC_AUTHENTICATION_PROVIDER_NAME:-""} # For SSO: Set to provider's JWKS URL (e.g., ["https://www.googleapis.com/oauth2/v3/certs"]) publicKeyUrls: ${AUTHENTICATION_PUBLIC_KEYS:-[http://localhost:8585/api/v1/system/config/jwks]} tokenValidationAlgorithm: ${AUTHENTICATION_TOKEN_VALIDATION_ALGORITHM:-"RS256"} authority: ${AUTHENTICATION_AUTHORITY:-https://accounts.google.com} clientId: ${AUTHENTICATION_CLIENT_ID:-""} # For SSO: Set to your OAuth callback URL (e.g., "https://yourhost/api/v1/callback") callbackUrl: ${AUTHENTICATION_CALLBACK_URL:-""} jwtPrincipalClaims: ${AUTHENTICATION_JWT_PRINCIPAL_CLAIMS:-[email,preferred_username,sub]} jwtPrincipalClaimsMapping: ${AUTHENTICATION_JWT_PRINCIPAL_CLAIMS_MAPPING:-[]} enableSelfSignup : ${AUTHENTICATION_ENABLE_SELF_SIGNUP:-true} enableAutoRedirect: ${AUTHENTICATION_ENABLE_AUTO_REDIRECT:-false} # Force secure flag on session cookies even when not using HTTPS directly. # Enable this when running behind a proxy/load balancer that handles SSL termination. # Default: false (secure flag only set when HTTPS is detected) forceSecureSessionCookie: ${FORCE_SECURE_SESSION_COOKIE:-false} sessionExpiry: ${AUTHENTICATION_SESSION_EXPIRY:-"604800"} # 7 days; applies to all auth providers maxActiveSessionsPerUser: ${AUTHENTICATION_MAX_ACTIVE_SESSIONS_PER_USER:-5} oidcConfiguration: # REQUIRED for SSO: OAuth client ID from your identity provider id: ${OIDC_CLIENT_ID:-""} # Set based on your provider: "google", "azure", "okta", "auth0", etc. type: ${OIDC_TYPE:-""} # REQUIRED for SSO: OAuth client secret from your identity provider (NEVER commit this!) secret: ${OIDC_CLIENT_SECRET:-""} scope: ${OIDC_SCOPE:-"openid email profile"} # OIDC discovery endpoint URL (e.g., "https://accounts.google.com/.well-known/openid-configuration") discoveryUri: ${OIDC_DISCOVERY_URI:-""} useNonce: ${OIDC_USE_NONCE:-true} preferredJwsAlgorithm: ${OIDC_PREFERRED_JWS:-"RS256"} responseType: ${OIDC_RESPONSE_TYPE:-"code"} disablePkce: ${OIDC_DISABLE_PKCE:-true} callbackUrl: ${OIDC_CALLBACK:-"http://localhost:8585/callback"} serverUrl: ${OIDC_SERVER_URL:-"http://localhost:8585"} clientAuthenticationMethod: ${OIDC_CLIENT_AUTH_METHOD:-"client_secret_post"} tenant: ${OIDC_TENANT:-""} maxClockSkew: ${OIDC_MAX_CLOCK_SKEW:-""} tokenValidity: ${OIDC_OM_REFRESH_TOKEN_VALIDITY:-"3600"} # in seconds customParams: ${OIDC_CUSTOM_PARAMS:-} maxAge: ${OIDC_MAX_AGE:-"0"} prompt: ${OIDC_PROMPT_TYPE:-"consent"} sessionExpiry: ${OIDC_SESSION_EXPIRY:-"604800"} # Deprecated fallback; use AUTHENTICATION_SESSION_EXPIRY samlConfiguration: debugMode: ${SAML_DEBUG_MODE:-false} idp: entityId: ${SAML_IDP_ENTITY_ID:-""} ssoLoginUrl: ${SAML_IDP_SSO_LOGIN_URL:-""} idpX509Certificate: ${SAML_IDP_CERTIFICATE:-""} nameId: ${SAML_IDP_NAME_ID:-"urn:oasis:names:tc:SAML:2.0:nameid-format:emailAddress"} sp: entityId: ${SAML_SP_ENTITY_ID:-"http://localhost:8585/api/v1/saml/metadata"} acs: ${SAML_SP_ACS:-"http://localhost:8585/api/v1/saml/acs"} spX509Certificate: ${SAML_SP_CERTIFICATE:-""} spPrivateKey: ${SAML_SP_PRIVATE_KEY:-""} callback: ${SAML_SP_CALLBACK:-"http://localhost:8585/saml/callback"} security: strictMode: ${SAML_STRICT_MODE:-false} validateXml: ${SAML_VALIDATE_XML:-false} tokenValidity: ${SAML_SP_TOKEN_VALIDITY:-"3600"} sendEncryptedNameId: ${SAML_SEND_ENCRYPTED_NAME_ID:-false} sendSignedAuthRequest: ${SAML_SEND_SIGNED_AUTH_REQUEST:-false} signSpMetadata: ${SAML_SIGNED_SP_METADATA:-false} wantMessagesSigned: ${SAML_WANT_MESSAGE_SIGNED:-false} wantAssertionsSigned: ${SAML_WANT_ASSERTION_SIGNED:-false} wantAssertionEncrypted: ${SAML_WANT_ASSERTION_ENCRYPTED:-false} keyStoreFilePath: ${SAML_KEYSTORE_FILE_PATH:-""} keyStoreAlias: ${SAML_KEYSTORE_ALIAS:-""} keyStorePassword: ${SAML_KEYSTORE_PASSWORD:-""} ldapConfiguration: host: ${AUTHENTICATION_LDAP_HOST:-} port: ${AUTHENTICATION_LDAP_PORT:-} dnAdminPrincipal: ${AUTHENTICATION_LOOKUP_ADMIN_DN:-""} dnAdminPassword: ${AUTHENTICATION_LOOKUP_ADMIN_PWD:-""} userBaseDN: ${AUTHENTICATION_USER_LOOKUP_BASEDN:-""} groupBaseDN: ${AUTHENTICATION_GROUP_LOOKUP_BASEDN:-""} roleAdminName: ${AUTHENTICATION_USER_ROLE_ADMIN_NAME:-} allAttributeName: ${AUTHENTICATION_USER_ALL_ATTR:-} mailAttributeName: ${AUTHENTICATION_USER_MAIL_ATTR:-} usernameAttributeName: ${AUTHENTICATION_USER_NAME_ATTR:-} groupAttributeName: ${AUTHENTICATION_USER_GROUP_ATTR:-} groupAttributeValue: ${AUTHENTICATION_USER_GROUP_ATTR_VALUE:-} groupMemberAttributeName: ${AUTHENTICATION_USER_GROUP_MEMBER_ATTR:-} #the mapping of roles to LDAP groups authRolesMapping: ${AUTH_ROLES_MAPPING:-""} authReassignRoles: ${AUTH_REASSIGN_ROLES:-[]} #optional maxPoolSize: ${AUTHENTICATION_LDAP_POOL_SIZE:-3} sslEnabled: ${AUTHENTICATION_LDAP_SSL_ENABLED:-} truststoreConfigType: ${AUTHENTICATION_LDAP_TRUSTSTORE_TYPE:-TrustAll} trustStoreConfig: customTrustManagerConfig: trustStoreFilePath: ${AUTHENTICATION_LDAP_TRUSTSTORE_PATH:-} trustStoreFilePassword: ${AUTHENTICATION_LDAP_KEYSTORE_PASSWORD:-} trustStoreFileFormat: ${AUTHENTICATION_LDAP_SSL_KEY_FORMAT:-} verifyHostname: ${AUTHENTICATION_LDAP_SSL_VERIFY_CERT_HOST:-} examineValidityDates: ${AUTHENTICATION_LDAP_EXAMINE_VALIDITY_DATES:-} hostNameConfig: allowWildCards: ${AUTHENTICATION_LDAP_ALLOW_WILDCARDS:-} acceptableHostNames: ${AUTHENTICATION_LDAP_ALLOWED_HOSTNAMES:-[]} jvmDefaultConfig: verifyHostname: ${AUTHENTICATION_LDAP_SSL_VERIFY_CERT_HOST:-} trustAllConfig: examineValidityDates: ${AUTHENTICATION_LDAP_EXAMINE_VALIDITY_DATES:-true} jwtTokenConfiguration: rsapublicKeyFilePath: ${RSA_PUBLIC_KEY_FILE_PATH:-"./conf/public_key.der"} rsaprivateKeyFilePath: ${RSA_PRIVATE_KEY_FILE_PATH:-"./conf/private_key.der"} jwtissuer: ${JWT_ISSUER:-"open-metadata.org"} keyId: ${JWT_KEY_ID:-"Gb389a-9f76-gdjs-a92j-0242bk94356"} elasticsearch: searchType: ${SEARCH_TYPE:- "elasticsearch"} # Single host or comma-separated list for multiple hosts # Examples: "localhost" or "es-node1:9200,es-node2:9200,es-node3:9200" host: ${ELASTICSEARCH_HOST:-localhost} port: ${ELASTICSEARCH_PORT:-9200} scheme: ${ELASTICSEARCH_SCHEME:-http} username: ${ELASTICSEARCH_USER:-""} password: ${ELASTICSEARCH_PASSWORD:-""} clusterAlias: ${ELASTICSEARCH_CLUSTER_ALIAS:-""} truststorePath: ${ELASTICSEARCH_TRUST_STORE_PATH:-""} truststorePassword: ${ELASTICSEARCH_TRUST_STORE_PASSWORD:-""} connectionTimeoutSecs: ${ELASTICSEARCH_CONNECTION_TIMEOUT_SECS:-10} # Increased from 5s for Docker networks socketTimeoutSecs: ${ELASTICSEARCH_SOCKET_TIMEOUT_SECS:-120} # Increased from 60s for slow queries keepAliveTimeoutSecs: ${ELASTICSEARCH_KEEP_ALIVE_TIMEOUT_SECS:-600} # Connection pool settings for better load balancing and performance maxConnTotal: ${ELASTICSEARCH_MAX_CONN_TOTAL:-30} # Total connections across all hosts maxConnPerRoute: ${ELASTICSEARCH_MAX_CONN_PER_ROUTE:-10} # Max connections per host batchSize: ${ELASTICSEARCH_BATCH_SIZE:-100} payLoadSize: ${ELASTICSEARCH_PAYLOAD_BYTES_SIZE:-10485760} searchIndexMappingLanguage : ${ELASTICSEARCH_INDEX_MAPPING_LANG:-EN} searchIndexFactoryClassName : org.openmetadata.service.search.SearchIndexFactory # AWS IAM Authentication for OpenSearch (only applicable when searchType is "opensearch") # Set enabled to true to use IAM authentication. When enabled, uses AWS credentials from: # - Environment variables: AWS_ACCESS_KEY_ID, AWS_SECRET_ACCESS_KEY, AWS_SESSION_TOKEN # - Or AWS SDK default credential provider chain (IAM roles, instance profiles, etc.) # Reference: https://docs.aws.amazon.com/cli/v1/userguide/cli-configure-envvars.html aws: enabled: ${SEARCH_AWS_IAM_AUTH_ENABLED:-false} region: ${AWS_DEFAULT_REGION:-""} accessKeyId: ${AWS_ACCESS_KEY_ID:-""} secretAccessKey: ${AWS_SECRET_ACCESS_KEY:-""} sessionToken: ${AWS_SESSION_TOKEN:-""} serviceName: ${SEARCH_AWS_SERVICE_NAME:-"es"} # Use "es" for OpenSearch, "aoss" for OpenSearch Serverless naturalLanguageSearch: enabled: ${NATURAL_LANGUAGE_SEARCH_ENABLED:-false} semanticSearchEnabled: ${SEMANTIC_SEARCH_ENABLED:-false} providerClass: ${NATURAL_LANGUAGE_SEARCH_PROVIDER_CLASS:-org.openmetadata.service.search.nlq.NoOpNLQService} # Embedding provider/model/credentials now live under llmConfiguration.embeddings (single LLM config home). # Platform-wide LLM provider configuration. Generic - consumed by any feature that needs LLM # completions (e.g. Context Center knowledge-pill extraction and the MCP Chat application). The # file content of uploaded documents is sent to the configured provider when enabled. Disabled by # default; set provider + credentials (or the matching env vars) to enable. llmConfiguration: enabled: ${LLM_ENABLED:-false} provider: ${LLM_PROVIDER:-noop} # noop | openai | azureOpenAI | bedrock | google | anthropic maxConcurrentRequests: ${LLM_MAX_CONCURRENT_REQUESTS:-5} openai: apiKey: ${LLM_OPENAI_API_KEY:-""} modelId: ${LLM_OPENAI_MODEL_ID:-"gpt-4o-mini"} endpoint: ${LLM_OPENAI_ENDPOINT:-""} # Set with deploymentName for Azure OpenAI deploymentName: ${LLM_OPENAI_DEPLOYMENT:-""} apiVersion: ${LLM_OPENAI_API_VERSION:-"2024-02-01"} maxTokens: ${LLM_OPENAI_MAX_TOKENS:-4096} bedrock: awsConfig: enabled: ${BEDROCK_AWS_IAM_AUTH_ENABLED:-true} region: ${AWS_DEFAULT_REGION:-""} accessKeyId: ${AWS_ACCESS_KEY_ID:-""} secretAccessKey: ${AWS_SECRET_ACCESS_KEY:-""} sessionToken: ${AWS_SESSION_TOKEN:-""} modelId: ${LLM_BEDROCK_MODEL_ID:-"eu.anthropic.claude-haiku-4-5-20251001-v1:0"} maxTokens: ${LLM_BEDROCK_MAX_TOKENS:-4096} google: apiKey: ${LLM_GOOGLE_API_KEY:-""} modelId: ${LLM_GOOGLE_MODEL_ID:-"gemini-2.5-flash"} maxTokens: ${LLM_GOOGLE_MAX_TOKENS:-4096} anthropic: apiKey: ${LLM_ANTHROPIC_API_KEY:-""} modelId: ${LLM_ANTHROPIC_MODEL_ID:-"claude-3-5-sonnet-20240620"} baseUrl: ${LLM_ANTHROPIC_BASE_URL:-"https://api.anthropic.com"} maxTokens: ${LLM_ANTHROPIC_MAX_TOKENS:-4096} # Vector embeddings for semantic search. Credentials reuse the provider blocks above # (bedrock.awsConfig, openai.apiKey/endpoint, google.apiKey); this section only selects the # embedding provider + model. The embedding provider may differ from the chat provider above. embeddings: provider: ${EMBEDDING_PROVIDER:-bedrock} # bedrock | openai | google | djl maxConcurrentRequests: ${MAX_CONCURRENT_EMBEDDING_REQUESTS:-10} bedrock: embeddingModelId: ${AWS_BEDROCK_EMBED_MODEL_ID:-"amazon.titan-embed-text-v2:0"} embeddingDimension: ${AWS_BEDROCK_EMBEDDING_DIMENSION:-512} openai: embeddingModelId: ${OPENAI_EMBEDDING_MODEL_ID:-"text-embedding-3-small"} embeddingDimension: ${OPENAI_EMBEDDING_DIMENSION:-1536} google: embeddingModelId: ${GOOGLE_EMBEDDING_MODEL_ID:-"gemini-embedding-001"} embeddingDimension: ${GOOGLE_EMBEDDING_DIMENSION:-768} djl: embeddingModel: ${DJL_EMBEDDING_MODEL:-"ai.djl.huggingface.pytorch/sentence-transformers/all-MiniLM-L6-v2"} eventMonitoringConfiguration: eventMonitor: ${EVENT_MONITOR:-prometheus} # Possible values are "prometheus", "cloudwatch" batchSize: ${EVENT_MONITOR_BATCH_SIZE:-10} pathPattern: ${EVENT_MONITOR_PATH_PATTERN:-["/api/v1/tables/*", "/api/v1/health-check"]} latency: ${EVENT_MONITOR_LATENCY:-[0.99, 0.90]} # For value p99=0.99, p90=0.90, p50=0.50 etc. servicesHealthCheckInterval: ${EVENT_MONITOR_SERVICES_HEALTH_CHECK_INTERVAL:-300} # it will use the default auth provider for AWS services if parameters are not set # parameters: # region: ${OM_MONITOR_REGION:-""} # accessKeyId: ${OM_MONITOR_ACCESS_KEY_ID:-""} # secretAccessKey: ${OM_MONITOR_ACCESS_KEY:-""} eventHandlerConfiguration: eventHandlerClassNames: - "org.openmetadata.service.events.AuditEventHandler" - "org.openmetadata.service.events.ChangeEventHandler" pipelineServiceClientConfiguration: enabled: ${PIPELINE_SERVICE_CLIENT_ENABLED:-true} # If we don't need this, set "org.openmetadata.service.clients.pipeline.noop.NoopClient" className: ${PIPELINE_SERVICE_CLIENT_CLASS_NAME:-"org.openmetadata.service.clients.pipeline.airflow.AirflowRESTClient"} apiEndpoint: ${PIPELINE_SERVICE_CLIENT_ENDPOINT:-http://localhost:8080} metadataApiEndpoint: ${SERVER_HOST_API_URL:-http://localhost:8585/api} ingestionIpInfoEnabled: ${PIPELINE_SERVICE_IP_INFO_ENABLED:-false} hostIp: ${PIPELINE_SERVICE_CLIENT_HOST_IP:-""} healthCheckInterval: ${PIPELINE_SERVICE_CLIENT_HEALTH_CHECK_INTERVAL:-300} # This SSL information is about the OpenMetadata server. # It will be picked up from the pipelineServiceClient to use/ignore SSL when connecting to the OpenMetadata server. verifySSL: ${PIPELINE_SERVICE_CLIENT_VERIFY_SSL:-"no-ssl"} # Possible values are "no-ssl", "ignore", "validate" sslConfig: certificatePath: ${PIPELINE_SERVICE_CLIENT_SSL_CERT_PATH:-""} # Local path for the Pipeline Service Client logStorageConfiguration: type: ${PIPELINE_SERVICE_CLIENT_LOG_TYPE:-"default"} # Possible values are "default", "s3" enabled: ${PIPELINE_SERVICE_CLIENT_LOG_ENABLED:-false} # Enable it for pipelines deployed in the server # if type is s3, provide the following configuration bucketName: ${PIPELINE_SERVICE_CLIENT_LOG_BUCKET_NAME:-""} # optional path within the bucket to store the logs prefix: ${PIPELINE_SERVICE_CLIENT_LOG_PREFIX:-""} enableServerSideEncryption: ${PIPELINE_SERVICE_CLIENT_LOG_SSE_ENABLED:-false} sseAlgorithm: ${PIPELINE_SERVICE_CLIENT_LOG_SSE_ALGORITHM:-"AES256"} # Allowed values: "AES256" or "aws:kms" kmsKeyId: ${PIPELINE_SERVICE_CLIENT_LOG_KMS_KEY_ID:-""} # Required only if sseAlgorithm is "aws:kms" awsConfig: enabled: ${PIPELINE_SERVICE_CLIENT_AWS_IAM_AUTH_ENABLED:-false} awsAccessKeyId: ${PIPELINE_SERVICE_CLIENT_LOG_AWS_ACCESS_KEY_ID:-""} awsSecretAccessKey: ${PIPELINE_SERVICE_CLIENT_LOG_AWS_SECRET_ACCESS_KEY:-""} awsRegion: ${PIPELINE_SERVICE_CLIENT_LOG_REGION:-""} awsSessionToken: ${PIPELINE_SERVICE_CLIENT_LOG_AWS_SESSION_TOKEN:-""} endPointURL: ${PIPELINE_SERVICE_CLIENT_LOG_AWS_ENDPOINT_URL:-""} # port forward localhost:9000 for minio # Secrets Manager Loader: specify to the Ingestion Framework how to load the SM credentials from its env # Supported: noop, airflow, env secretsManagerLoader: ${PIPELINE_SERVICE_CLIENT_SECRETS_MANAGER_LOADER:-"noop"} # Default required parameters for Airflow as Pipeline Service Client parameters: ## Airflow parameters username: ${AIRFLOW_USERNAME:-admin} password: ${AIRFLOW_PASSWORD:-admin} timeout: ${AIRFLOW_TIMEOUT:-10} # If we need to use SSL to reach Airflow truststorePath: ${AIRFLOW_TRUST_STORE_PATH:-""} truststorePassword: ${AIRFLOW_TRUST_STORE_PASSWORD:-""} ## Kubernetes client parameters namespace: ${K8S_NAMESPACE:-"openmetadata-pipelines"} ingestionImage: ${K8S_INGESTION_IMAGE:-"docker.getcollate.io/openmetadata/ingestion-base:latest"} imagePullPolicy: ${K8S_IMAGE_PULL_POLICY:-"IfNotPresent"} imagePullSecrets: ${K8S_IMAGE_PULL_SECRETS:-""} serviceAccountName: ${K8S_SERVICE_ACCOUNT_NAME:-"openmetadata-ingestion"} # Resources configuration resources: limits: cpu: ${K8S_LIMITS_CPU:-"2"} memory: ${K8S_LIMITS_MEMORY:-"4Gi"} requests: cpu: ${K8S_REQUESTS_CPU:-"500m"} memory: ${K8S_REQUESTS_MEMORY:-"1Gi"} ttlSecondsAfterFinished: ${K8S_TTL_SECONDS_AFTER_FINISHED:-604800} activeDeadlineSeconds: ${K8S_ACTIVE_DEADLINE_SECONDS:-604800} backoffLimit: ${K8S_BACKOFF_LIMIT:-3} successfulJobsHistoryLimit: ${K8S_SUCCESSFUL_JOBS_HISTORY_LIMIT:-3} failedJobsHistoryLimit: ${K8S_FAILED_JOBS_HISTORY_LIMIT:-1} nodeSelector: ${K8S_NODE_SELECTOR:-""} runAsUser: ${K8S_RUN_AS_USER:-1000} runAsGroup: ${K8S_RUN_AS_GROUP:-1000} fsGroup: ${K8S_FS_GROUP:-1000} runAsNonRoot: ${K8S_RUN_AS_NON_ROOT:-"true"} extraEnvVars: ${K8S_EXTRA_ENV_VARS:-[]} podAnnotations: ${K8S_POD_ANNOTATIONS:-""} tolerations: ${K8S_TOLERATIONS:-[]} useOMJobOperator: ${USE_OMJOB_OPERATOR:-"true"} # no_encryption_at_rest is the default value, and it does what it says. Please read the manual on how # to secure your instance of OpenMetadata with TLS and encryption at rest. fernetConfiguration: fernetKey: ${FERNET_KEY:-jJ/9sz0g0OHxsfxOoSfdFdmk3ysNmPRnH3TUAbz3IHA=} secretsManagerConfiguration: secretsManager: ${SECRET_MANAGER:-db} # Possible values are "db", "managed-aws","aws", "managed-aws-ssm", "aws-ssm", "managed-azure-kv", "azure-kv", "in-memory", "gcp", "kubernetes" prefix: ${SECRET_MANAGER_PREFIX:-""} # Define the secret key ID as /// tags: ${SECRET_MANAGER_TAGS:-[]} # Add tags to the created resource. Format is `[key1:value1,key2:value2,...]` # it will use the default auth provider for the secrets' manager service if parameters are not set parameters: ## For AWS region: ${OM_SM_REGION:-""} accessKeyId: ${OM_SM_ACCESS_KEY_ID:-""} secretAccessKey: ${OM_SM_ACCESS_KEY:-""} ## For Azure Key Vault clientId: ${OM_SM_CLIENT_ID:-""} clientSecret: ${OM_SM_CLIENT_SECRET:-""} tenantId: ${OM_SM_TENANT_ID:-""} vaultName: ${OM_SM_VAULT_NAME:-""} ## For GCP projectId: ${OM_SM_PROJECT_ID:-""} ## For Kubernetes namespace: ${OM_SM_NAMESPACE:-"default"} kubeconfigPath: ${OM_SM_KUBECONFIG_PATH:-""} inCluster: ${OM_SM_IN_CLUSTER:-"false"} health: delayedShutdownHandlerEnabled: true shutdownWaitPeriod: 1s healthChecks: - name: OpenMetadataServerHealthCheck critical: true schedule: checkInterval: 2500ms downtimeInterval: 10s failureAttempts: 2 successAttempts: 1 limits: enable: ${LIMITS_ENABLED:-false} className: ${LIMITS_CLASS_NAME:-"org.openmetadata.service.limits.DefaultLimits"} limitsConfigFile: ${LIMITS_CONFIG_FILE:-""} # Bulk Operation Configuration # Controls parallelism and admission control for bulk API operations. bulkOperation: # Max threads for processing maxThreads: ${BULK_OPERATION_MAX_THREADS:-10} # Max queued operations before rejection (returns 503) queueSize: ${BULK_OPERATION_QUEUE_SIZE:-1000} # Timeout in seconds for entire bulk operation timeoutSeconds: ${BULK_OPERATION_TIMEOUT_SECONDS:-300} web: uriPath: ${WEB_CONF_URI_PATH:-"/api"} hsts: enabled: ${WEB_CONF_HSTS_ENABLED:-false} maxAge: ${WEB_CONF_HSTS_MAX_AGE:-"365 days"} includeSubDomains: ${WEB_CONF_HSTS_INCLUDE_SUBDOMAINS:-"true"} preload: ${WEB_CONF_HSTS_PRELOAD:-"true"} frame-options: enabled: ${WEB_CONF_FRAME_OPTION_ENABLED:-false} option: ${WEB_CONF_FRAME_OPTION:-"SAMEORIGIN"} origin: ${WEB_CONF_FRAME_ORIGIN:-""} content-type-options: enabled: ${WEB_CONF_CONTENT_TYPE_OPTIONS_ENABLED:-false} xss-protection: enabled: ${WEB_CONF_XSS_PROTECTION_ENABLED:-false} on: ${WEB_CONF_XSS_PROTECTION_ON:-true} block: ${WEB_CONF_XSS_PROTECTION_BLOCK:-true} csp: enabled: ${WEB_CONF_XSS_CSP_ENABLED:-false} # default-src 'self'; base-uri 'self'; script-src 'self' 'nonce-__CSP_NONCE__' https://www.googletagmanager.com; style-src 'self' 'unsafe-inline' https://fonts.googleapis.com; font-src 'self' https://fonts.gstatic.com data:; img-src * 'self' blob: data:; media-src * 'self' blob:; worker-src 'self' blob:; frame-src 'self' https://www.youtube.com; object-src 'none'; connect-src 'self'; policy: ${WEB_CONF_XSS_CSP_POLICY:-""} reportOnlyPolicy: ${WEB_CONF_XSS_CSP_REPORT_ONLY_POLICY:-""} referrer-policy: enabled: ${WEB_CONF_REFERRER_POLICY_ENABLED:-false} option: ${WEB_CONF_REFERRER_POLICY_OPTION:-"SAME_ORIGIN"} permission-policy: enabled: ${WEB_CONF_PERMISSION_POLICY_ENABLED:-false} option: ${WEB_CONF_PERMISSION_POLICY_OPTION:-""} cross-origin-embedder-policy: enabled: ${WEB_CONF_CROSS_ORIGIN_EMBEDDER_POLICY_ENABLED:-false} option: ${WEB_CONF_CROSS_ORIGIN_EMBEDDER_POLICY_OPTION:-"REQUIRE_CORP"} cross-origin-resource-policy: enabled: ${WEB_CONF_CROSS_ORIGIN_RESOURCE_POLICY_ENABLED:-false} option: ${WEB_CONF_CROSS_ORIGIN_RESOURCE_POLICY_OPTION:-"SAME_ORIGIN"} cross-origin-opener-policy: enabled: ${WEB_CONF_CROSS_ORIGIN_OPENER_POLICY_ENABLED:-false} option: ${WEB_CONF_CROSS_ORIGIN_OPENER_POLICY_OPTION:-"SAME_ORIGIN"} cache-control: ${WEB_CONF_CACHE_CONTROL:-""} pragma: ${WEB_CONF_PRAGMA:-""} operationalConfig: enable: ${OPERATIONAL_CONFIG_ENABLED:-true} operationsConfigFile: ${OPERATIONAL_CONFIG_FILE:-"./conf/operations.yaml"} rdf: enabled: ${RDF_ENABLED:-false} baseUri: ${RDF_BASE_URI:-"https://open-metadata.org/"} storageType: ${RDF_STORAGE_TYPE:-"FUSEKI"} remoteEndpoint: ${RDF_ENDPOINT:-"http://localhost:3030/openmetadata"} connectTimeoutMs: ${RDF_CONNECT_TIMEOUT_MS:-2000} requestTimeoutMs: ${RDF_REQUEST_TIMEOUT_MS:-60000} writeMaxRetries: ${RDF_WRITE_MAX_RETRIES:-2} writeRetryInitialBackoffMs: ${RDF_WRITE_RETRY_INITIAL_BACKOFF_MS:-250} writeRetryMaxBackoffMs: ${RDF_WRITE_RETRY_MAX_BACKOFF_MS:-2000} bulkEntityBatchSize: ${RDF_BULK_ENTITY_BATCH_SIZE:-50} bulkRelationshipSourceBatchSize: ${RDF_BULK_RELATIONSHIP_SOURCE_BATCH_SIZE:-25} username: ${RDF_REMOTE_USERNAME:-"admin"} password: ${RDF_REMOTE_PASSWORD:-"admin"} dataset: ${RDF_DATASET:-"openmetadata"} # Cache Configuration # Caching layer for entity metadata, relationships, and tag usage to reduce database load # Default: none (no external dependency). Set CACHE_PROVIDER=redis to enable the # Redis L2 cache; it falls back to NoopCacheProvider if Redis is unreachable at startup. cache: # Cache provider: none (default) or redis provider: ${CACHE_PROVIDER:-none} # TTL (Time To Live) settings in seconds entityTtlSeconds: ${CACHE_ENTITY_TTL:-172800} # 48 hour for entities relationshipTtlSeconds: ${CACHE_RELATIONSHIP_TTL:-172800} # 48 hour for relationships tagTtlSeconds: ${CACHE_TAG_TTL:-172800} # 48 hour for tags # Redis configuration redis: # Redis connection URL # Standalone: redis://localhost:6379 # AWS ElastiCache: redis://my-cluster.abc123.cache.amazonaws.com:6379 url: ${CACHE_REDIS_URL:-redis://localhost:6379} authType: ${CACHE_REDIS_AUTH_TYPE:-NONE} database: ${CACHE_REDIS_DATABASE:-0} # Redis database index (0-15) # Authentication for standalone Redis username: ${CACHE_REDIS_USERNAME:-} passwordRef: ${CACHE_REDIS_PASSWORD:-} # Reference to password in secrets manager useSSL: ${CACHE_REDIS_USE_SSL:-false} # Key namespace prefix (useful for multi-tenant deployments) keyspace: ${CACHE_REDIS_KEYSPACE:-"om:prod"} # Connection pool settings poolSize: ${CACHE_REDIS_POOL_SIZE:-64} connectTimeoutMs: ${CACHE_REDIS_CONNECT_TIMEOUT:-2000} # Per-command timeout. Bounds request-thread blocking when Redis is slow. commandTimeoutMs: ${CACHE_REDIS_COMMAND_TIMEOUT:-300} # AWS ElastiCache IAM Authentication (only if using ElastiCache) aws: enabled: ${CACHE_REDIS_AWS_IAM_AUTH_ENABLED:-false} region: ${CACHE_REDIS_AWS_REGION:-""} useInstanceProfile: ${CACHE_REDIS_AWS_INSTANCE_PROFILE:-true} # If not using instance profile, provide credentials: accessKeyId: ${AWS_ACCESS_KEY_ID:-""} secretAccessKey: ${AWS_SECRET_ACCESS_KEY:-""} tokenRefreshIntervalSeconds: ${CACHE_REDIS_TOKEN_REFRESH:-900} # 15 minutes