Files
backend_supabase/volumes/api/envoy/lds.template.yaml
Elzo codeur cb7c512c57 first commit
2026-06-11 21:28:31 +00:00

995 lines
44 KiB
YAML
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

resources:
- '@type': type.googleapis.com/envoy.config.listener.v3.Listener
name: supabase
per_connection_buffer_limit_bytes: 32768 # 32 KiB
address:
socket_address:
address: 0.0.0.0
port_value: 8000
filter_chains:
- filters:
- name: envoy.filters.network.http_connection_manager
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.network.http_connection_manager.v3.HttpConnectionManager
stat_prefix: ingress_http
normalize_path: true
merge_slashes: true
path_with_escaped_slashes_action: REJECT_REQUEST
use_remote_address: true
common_http_protocol_options:
headers_with_underscores_action: REJECT_REQUEST
upgrade_configs:
- upgrade_type: websocket
access_log:
- name: envoy.access_loggers.stdout
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.access_loggers.stream.v3.StdoutAccessLog
log_format:
text_format_source:
inline_string: "%DOWNSTREAM_REMOTE_ADDRESS_WITHOUT_PORT% - - [%START_TIME(%d/%b/%Y:%H:%M:%S %z)%] \"%REQ(:METHOD)% %REQ(X-ENVOY-ORIGINAL-PATH?:PATH)% %PROTOCOL%\" %RESPONSE_CODE% %BYTES_SENT% \"%REQ(REFERER)%\" \"%REQ(USER-AGENT)%\"\n"
route_config:
name: supabase_route
virtual_hosts:
- name: supabase_host
domains:
- '*'
cors:
allow_origin_string_match:
- safe_regex:
regex: ".*"
allow_methods: "GET,POST,PUT,PATCH,DELETE,OPTIONS,HEAD,CONNECT,TRACE"
allow_headers: "*"
expose_headers: "*"
max_age: "3600"
request_headers_to_add:
- header:
key: X-Forwarded-Host
value: "%REQ(:AUTHORITY)%"
append_action: ADD_IF_ABSENT
- header:
key: X-Forwarded-Port
value: "%DOWNSTREAM_LOCAL_PORT%"
append_action: ADD_IF_ABSENT
routes:
- match:
prefix: /auth/v1/verify
route:
cluster: auth
prefix_rewrite: /verify
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /auth/v1/verify
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /auth/v1/callback
route:
cluster: auth
prefix_rewrite: /callback
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /auth/v1/callback
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /auth/v1/authorize
route:
cluster: auth
prefix_rewrite: /authorize
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /auth/v1/authorize
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /auth/v1/.well-known/jwks.json
route:
cluster: auth
prefix_rewrite: /.well-known/jwks.json
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /auth/v1/.well-known/jwks.json
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /.well-known/oauth-authorization-server
route:
cluster: auth
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /.well-known/oauth-authorization-server
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /sso/saml/acs
route:
cluster: auth
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /sso/saml/acs
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /sso/saml/metadata
route:
cluster: auth
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /sso/saml/metadata
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- name: functions-v1-all
match:
prefix: /functions/v1/
route:
cluster: functions
prefix_rewrite: /
timeout: 150s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /functions/v1/
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /storage/v1/
route:
cluster: storage
prefix_rewrite: /
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /storage/v1
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
- name: auth-v1-protected
match:
prefix: /auth/v1/
route:
cluster: auth
prefix_rewrite: /
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /auth/v1/
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
- name: rest-v1-protected
match:
prefix: /rest/v1/
route:
cluster: rest
prefix_rewrite: /
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /rest/v1/
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
- name: graphql-v1-protected
match:
prefix: /graphql/v1
route:
cluster: rest
prefix_rewrite: /rpc/graphql
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /graphql/v1
append_action: ADD_IF_ABSENT
- header:
key: Content-Profile
value: graphql_public
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
- name: realtime-v1-api-protected
match:
prefix: /realtime/v1/api
route:
cluster: realtime
prefix_rewrite: /api
timeout: 30s
host_rewrite_literal: realtime-dev.supabase-realtime
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /realtime/v1/api
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
- name: realtime-v1-ws-protected
match:
prefix: /realtime/v1/
route:
cluster: realtime
prefix_rewrite: /socket/
timeout: 30s
host_rewrite_literal: realtime-dev.supabase-realtime
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /realtime/v1/
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
- name: pg-protected
match:
prefix: /pg/
route:
cluster: meta
prefix_rewrite: /
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /pg/
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
- match:
prefix: /api/mcp
route:
cluster: studio
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /api/mcp
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: DENY
policies:
deny_all:
permissions:
- any: true
principals:
- any: true
- match:
prefix: /mcp
route:
cluster: studio
prefix_rewrite: /api/mcp
timeout: 30s
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /mcp
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.basic_auth:
'@type': >-
type.googleapis.com/envoy.config.route.v3.FilterConfig
disabled: true
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
# Block access to /mcp by default
rbac:
rules:
action: DENY
policies:
deny_all:
permissions:
- any: true
principals:
- any: true
# Enable local access (danger zone!)
# 1. Comment out the 'rbac' block above.
# 2. Uncomment and adjust the 'rbac' block below.
# 3. Add or adjust your local IPs in 'principals'.
#rbac:
# rules:
# action: ALLOW
# policies:
# allow_local:
# permissions:
# - any: true
# principals:
# - direct_remote_ip:
# address_prefix: 127.0.0.1
# prefix_len: 32
# - direct_remote_ip:
# address_prefix: ::1
# prefix_len: 128
- match:
prefix: /
route:
cluster: studio
timeout: 30s
request_headers_to_remove:
- authorization
request_headers_to_add:
- header:
key: X-Forwarded-Prefix
value: /
append_action: ADD_IF_ABSENT
typed_per_filter_config:
envoy.filters.http.rbac:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBACPerRoute
rbac:
rules:
action: ALLOW
policies:
allow_all:
permissions:
- any: true
principals:
- any: true
http_filters:
- name: envoy.filters.http.cors
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.cors.v3.Cors
- name: envoy.filters.http.basic_auth
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.basic_auth.v3.BasicAuth
users:
inline_string: '${DASHBOARD_BASIC_AUTH}'
# Copies ?apikey=... from the URL into the apikey header when clients omit the header.
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local FUNCTIONS_ROUTE = "functions-v1-all"
local FUNCTIONS_PREFIX = "/functions/v1/"
local function is_functions_request(request_handle, headers)
if request_handle:streamInfo():routeName() == FUNCTIONS_ROUTE then
return true
end
local path = headers:get(":path")
if path == nil then
return false
end
return string.sub(path, 1, string.len(FUNCTIONS_PREFIX)) == FUNCTIONS_PREFIX
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
if is_functions_request(request_handle, headers) then
return
end
if headers:get("apikey") ~= nil then
return
end
local path = headers:get(":path")
local query_start = string.find(path, "?", 1, true)
if query_start == nil then
return
end
local query = string.sub(path, query_start + 1)
for key, value in string.gmatch(query, "([^&]+)=([^&]*)") do
if key == "apikey" and value ~= "" then
headers:add("apikey", value)
return
end
end
end
# Returns 401 for missing/invalid API keys on protected API routes.
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local ANON_KEY = "${ANON_KEY}"
local SERVICE_ROLE_KEY = "${SERVICE_ROLE_KEY}"
local SUPABASE_PUBLISHABLE_KEY = "${SUPABASE_PUBLISHABLE_KEY}"
local SUPABASE_SECRET_KEY = "${SUPABASE_SECRET_KEY}"
local ANON_KEY_ASYMMETRIC = "${ANON_KEY_ASYMMETRIC}"
local SERVICE_ROLE_KEY_ASYMMETRIC = "${SERVICE_ROLE_KEY_ASYMMETRIC}"
local TRANSLATION_ENABLED = SUPABASE_SECRET_KEY ~= "" and SUPABASE_PUBLISHABLE_KEY ~= "" and SERVICE_ROLE_KEY_ASYMMETRIC ~= "" and ANON_KEY_ASYMMETRIC ~= ""
local PROTECTED_ROUTES = {
["auth-v1-protected"] = true,
["rest-v1-protected"] = true,
["graphql-v1-protected"] = true,
["realtime-v1-api-protected"] = true,
["realtime-v1-ws-protected"] = true,
["pg-protected"] = true,
}
local function is_protected_route(route_name)
if route_name == nil or route_name == "" then
return false
end
return PROTECTED_ROUTES[route_name] == true
end
local function is_valid_apikey(apikey)
if apikey == nil or apikey == "" then
return false
end
if SERVICE_ROLE_KEY ~= "" and apikey == SERVICE_ROLE_KEY then
return true
end
if ANON_KEY ~= "" and apikey == ANON_KEY then
return true
end
if TRANSLATION_ENABLED and apikey == SUPABASE_SECRET_KEY then
return true
end
if TRANSLATION_ENABLED and apikey == SUPABASE_PUBLISHABLE_KEY then
return true
end
return false
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
local route_name = request_handle:streamInfo():routeName()
if not is_protected_route(route_name) then
return
end
if is_valid_apikey(headers:get("apikey")) then
return
end
request_handle:respond({
[":status"] = "401",
["content-type"] = "text/plain",
}, "Unauthorized")
end
# Translates the query parameter apikey into the matching internal JWT and rewrites the URL so only JWTs propagate downstream.
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local FUNCTIONS_ROUTE = "functions-v1-all"
local FUNCTIONS_PREFIX = "/functions/v1/"
local SECRET_KEY = "${SUPABASE_SECRET_KEY}"
local PUBLISHABLE_KEY = "${SUPABASE_PUBLISHABLE_KEY}"
local SERVICE_ROLE_JWT = "${SERVICE_ROLE_KEY_ASYMMETRIC}"
local ANON_JWT = "${ANON_KEY_ASYMMETRIC}"
local TRANSLATION_ENABLED = SECRET_KEY ~= "" and PUBLISHABLE_KEY ~= "" and SERVICE_ROLE_JWT ~= "" and ANON_JWT ~= ""
local function is_functions_request(request_handle, headers)
if request_handle:streamInfo():routeName() == FUNCTIONS_ROUTE then
return true
end
local path = headers:get(":path")
if path == nil then
return false
end
return string.sub(path, 1, string.len(FUNCTIONS_PREFIX)) == FUNCTIONS_PREFIX
end
local function translate_apikey(apikey)
if apikey == nil or apikey == "" then
return nil
end
if not TRANSLATION_ENABLED then
return nil
end
if apikey == SECRET_KEY then
return SERVICE_ROLE_JWT
end
if apikey == PUBLISHABLE_KEY then
return ANON_JWT
end
return nil
end
local function extract_query_apikey(path)
if path == nil or path == "" then
return nil
end
local query_start = string.find(path, "?", 1, true)
if query_start == nil then
return nil
end
local query = string.sub(path, query_start + 1)
for key, value in string.gmatch(query, "([^&]+)=([^&]*)") do
if key == "apikey" and value ~= "" then
return value
end
end
return nil
end
local function replace_query_apikey(path, new_value)
if path == nil or path == "" or new_value == nil or new_value == "" then
return nil
end
local query_start = string.find(path, "?", 1, true)
if query_start == nil then
return nil
end
local base = string.sub(path, 1, query_start)
local query = string.sub(path, query_start + 1)
local updated = {}
local replaced = false
for part in string.gmatch(query, "([^&]+)") do
local key, value = string.match(part, "([^=]+)=(.*)")
if key == "apikey" then
part = key .. "=" .. new_value
replaced = true
end
table.insert(updated, part)
end
if not replaced then
return nil
end
return base .. table.concat(updated, "&")
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
if is_functions_request(request_handle, headers) then
return
end
local path = headers:get(":path")
local apikey = extract_query_apikey(path)
local translated = translate_apikey(apikey)
if translated == nil then
return
end
headers:replace("apikey", translated)
local rewritten_path = replace_query_apikey(path, translated)
if rewritten_path ~= nil then
headers:replace(":path", rewritten_path)
end
end
# Translates an apikey header into the appropriate internal JWT for downstream RBAC checks.
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local FUNCTIONS_ROUTE = "functions-v1-all"
local FUNCTIONS_PREFIX = "/functions/v1/"
local SECRET_KEY = "${SUPABASE_SECRET_KEY}"
local PUBLISHABLE_KEY = "${SUPABASE_PUBLISHABLE_KEY}"
local SERVICE_ROLE_JWT = "${SERVICE_ROLE_KEY_ASYMMETRIC}"
local ANON_JWT = "${ANON_KEY_ASYMMETRIC}"
local TRANSLATION_ENABLED = SECRET_KEY ~= "" and PUBLISHABLE_KEY ~= "" and SERVICE_ROLE_JWT ~= "" and ANON_JWT ~= ""
local function is_functions_request(request_handle, headers)
if request_handle:streamInfo():routeName() == FUNCTIONS_ROUTE then
return true
end
local path = headers:get(":path")
if path == nil then
return false
end
return string.sub(path, 1, string.len(FUNCTIONS_PREFIX)) == FUNCTIONS_PREFIX
end
local function translate_apikey(apikey)
if apikey == nil or apikey == "" then
return nil
end
if not TRANSLATION_ENABLED then
return nil
end
if apikey == SECRET_KEY then
return SERVICE_ROLE_JWT
end
if apikey == PUBLISHABLE_KEY then
return ANON_JWT
end
return nil
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
if is_functions_request(request_handle, headers) then
return
end
local translated = translate_apikey(headers:get("apikey"))
if translated ~= nil and translated ~= "" then
headers:replace("apikey", translated)
end
end
# Mirrors apikey into x-api-key for realtime WS compatibility.
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local REALTIME_WS_ROUTE = "realtime-v1-ws-protected"
function envoy_on_request(request_handle)
local route_name = request_handle:streamInfo():routeName()
if route_name ~= REALTIME_WS_ROUTE then
return
end
local headers = request_handle:headers()
local apikey = headers:get("apikey")
if apikey == nil or apikey == "" then
return
end
headers:replace("x-api-key", apikey)
end
# Synthesizes an Authorization header (Bearer …) from apikey when callers dont provide a real JWT header.
- name: envoy.filters.http.lua
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.lua.v3.Lua
inline_code: |
local FUNCTIONS_ROUTE = "functions-v1-all"
local FUNCTIONS_PREFIX = "/functions/v1/"
local REALTIME_WS_ROUTE = "realtime-v1-ws-protected"
local function is_functions_request(request_handle, headers)
if request_handle:streamInfo():routeName() == FUNCTIONS_ROUTE then
return true
end
local path = headers:get(":path")
if path == nil then
return false
end
return string.sub(path, 1, string.len(FUNCTIONS_PREFIX)) == FUNCTIONS_PREFIX
end
local function has_real_jwt(auth_header)
if auth_header == nil or auth_header == "" then
return false
end
if string.sub(auth_header, 1, 7) ~= "Bearer " then
return false
end
return string.sub(auth_header, 1, 10) ~= "Bearer sb_"
end
local function format_authorization(value)
if value == nil or value == "" then
return nil
end
if string.sub(value, 1, 7) == "Bearer " then
return value
end
return "Bearer " .. value
end
function envoy_on_request(request_handle)
local headers = request_handle:headers()
if request_handle:streamInfo():routeName() == REALTIME_WS_ROUTE then
return
end
if is_functions_request(request_handle, headers) then
return
end
if has_real_jwt(headers:get("authorization")) then
return
end
local apikey = headers:get("apikey")
local authorization_value = format_authorization(apikey)
if authorization_value ~= nil then
headers:replace("authorization", authorization_value)
end
end
- name: envoy.filters.http.rbac
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.rbac.v3.RBAC
rules:
action: ALLOW
policies:
admin:
permissions:
- url_path:
path:
prefix: /pg/
principals:
- header:
name: apikey
string_match:
exact: '${SERVICE_ROLE_KEY}'
- header:
name: apikey
string_match:
exact: '${SERVICE_ROLE_KEY_ASYMMETRIC}'
apikey:
permissions:
- url_path:
path:
prefix: /auth/v1/
- url_path:
path:
prefix: /rest/v1/
- url_path:
path:
prefix: /realtime/v1/api
- url_path:
path:
prefix: /realtime/v1/
- url_path:
path:
prefix: /graphql/v1
principals:
- header:
name: apikey
string_match:
exact: '${SERVICE_ROLE_KEY}'
- header:
name: apikey
string_match:
exact: '${ANON_KEY}'
- header:
name: apikey
string_match:
exact: '${SERVICE_ROLE_KEY_ASYMMETRIC}'
- header:
name: apikey
string_match:
exact: '${ANON_KEY_ASYMMETRIC}'
- name: envoy.filters.http.router
typed_config:
'@type': >-
type.googleapis.com/envoy.extensions.filters.http.router.v3.Router