Ctrl K
ComunidadGuías…

supabase-nano/kong/kong.yml

Rama main · réplica de lectura del repositorio original.

Archivo original ↗Preguntar a KiBot
_format_version: '2.1'
_transform: true

###
### Consumers / Users
###
consumers:
  - username: DASHBOARD
  - username: anon
    keyauth_credentials:
      - key: $SUPABASE_ANON_KEY
      - key: $SUPABASE_PUBLISHABLE_KEY
  - username: service_role
    keyauth_credentials:
      - key: $SUPABASE_SERVICE_KEY
      - key: $SUPABASE_SECRET_KEY

###
### Access Control List
###
acls:
  - consumer: anon
    group: anon
  - consumer: service_role
    group: admin

###
### Dashboard credentials
###
basicauth_credentials:
  - consumer: DASHBOARD
    username: '$DASHBOARD_USERNAME'
    password: '$DASHBOARD_PASSWORD'

###
### API Routes
###
services:
  ## Open Auth routes
  - name: auth-v1-open
    _comment: 'Auth: /auth/v1/verify* -> http://supabase-auth:9999/verify*'
    url: http://supabase-auth:9999/verify
    routes:
      - name: auth-v1-open
        strip_path: true
        paths:
          - /auth/v1/verify
    plugins:
      - name: cors
  - name: auth-v1-open-callback
    _comment: 'Auth: /auth/v1/callback* -> http://supabase-auth:9999/callback*'
    url: http://supabase-auth:9999/callback
    routes:
      - name: auth-v1-open-callback
        strip_path: true
        paths:
          - /auth/v1/callback
    plugins:
      - name: cors
  - name: auth-v1-open-authorize
    _comment: 'Auth: /auth/v1/authorize* -> http://supabase-auth:9999/authorize*'
    url: http://supabase-auth:9999/authorize
    routes:
      - name: auth-v1-open-authorize
        strip_path: true
        paths:
          - /auth/v1/authorize
    plugins:
      - name: cors
  - name: auth-v1-open-jwks
    _comment: 'Auth: /auth/v1/.well-known/jwks.json -> http://supabase-auth:9999/.well-known/jwks.json'
    url: http://supabase-auth:9999/.well-known/jwks.json
    routes:
      - name: auth-v1-open-jwks
        strip_path: true
        paths:
          - /auth/v1/.well-known/jwks.json
    plugins:
      - name: cors

  - name: auth-v1-open-sso-acs
    url: "http://supabase-auth:9999/sso/saml/acs"
    routes:
      - name: auth-v1-open-sso-acs
        strip_path: true
        paths:
        - /sso/saml/acs
    plugins:
      - name: cors
      
  - name: auth-v1-open-sso-metadata
    url: "http://supabase-auth:9999/sso/saml/metadata"
    routes:
      - name: auth-v1-open-sso-metadata
        strip_path: true
        paths:
        - /sso/saml/metadata
    plugins:
      - name: cors

  ## Secure Auth routes
  - name: auth-v1
    _comment: 'Auth: /auth/v1/* -> http://supabase-auth:9999/*'
    url: http://supabase-auth:9999/
    routes:
      - name: auth-v1-all
        strip_path: true
        paths:
          - /auth/v1/
    plugins:
      - name: cors
      - name: key-auth
        config:
          hide_credentials: false
      - name: request-transformer
        config:
          add:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
          replace:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
      - name: acl
        config:
          hide_groups_header: true
          allow:
            - admin
            - anon

  ## Secure PostgREST routes
  - name: rest-v1
    _comment: 'PostgREST: /rest/v1/* -> http://supabase-rest:3000/*'
    url: http://supabase-rest:3000/
    routes:
      - name: rest-v1-all
        strip_path: true
        paths:
          - /rest/v1/
    plugins:
      - name: cors
      - name: key-auth
        config:
          hide_credentials: false
      - name: request-transformer
        config:
          add:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
          replace:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
      - name: acl
        config:
          hide_groups_header: true
          allow:
            - admin
            - anon

  ## Secure GraphQL routes
  - name: graphql-v1
    _comment: 'PostgREST: /graphql/v1/* -> http://supabase-rest:3000/rpc/graphql'
    url: http://supabase-rest:3000/rpc/graphql
    routes:
      - name: graphql-v1-all
        strip_path: true
        paths:
          - /graphql/v1
    plugins:
      - name: cors
      - name: key-auth
        config:
          hide_credentials: false
      - name: request-transformer
        config:
          add:
            headers:
              - "Content-Profile: graphql_public"
              - "Authorization: $LUA_AUTH_EXPR"
          replace:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
      - name: acl
        config:
          hide_groups_header: true
          allow:
            - admin
            - anon

  ## Secure Realtime routes
  - name: realtime-v1-ws
    _comment: 'Realtime: /realtime/v1/* -> ws://realtime:4000/socket/*'
    url: http://supabase-realtime:4000/socket
    protocol: ws
    routes:
      - name: realtime-v1-ws
        strip_path: true
        paths:
          - /realtime/v1/
    plugins:
      - name: cors
      - name: key-auth
        config:
          hide_credentials: false
      - name: request-transformer
        config:
          add:
            headers:
              - "x-api-key:$LUA_RT_WS_EXPR"
          replace:
            querystring:
              - "apikey:$LUA_RT_WS_EXPR"
      - name: acl
        config:
          hide_groups_header: true
          allow:
            - admin
            - anon

  - name: realtime-v1-rest
    _comment: 'Realtime: /realtime/v1/api/* -> http://supabase-realtime:4000/api/*'
    url: http://supabase-realtime:4000/api
    protocol: http
    routes:
      - name: realtime-v1-rest
        strip_path: true
        paths:
          - /realtime/v1/api
    plugins:
      - name: cors
      - name: key-auth
        config:
          hide_credentials: false
      - name: request-transformer
        config:
          add:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
          replace:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
      - name: acl
        config:
          hide_groups_header: true
          allow:
            - admin
            - anon

  ## Storage API endpoint (with Authorization header transformation).
  ## No key-auth, S3 protocol requests don't carry an apikey header.
  ##
  ## The request-transformer translates opaque API keys to asymmetric JWTs
  ## and passes through existing Authorization headers (user JWTs, AWS SigV4).
  ## When no Authorization or apikey header is present (S3 presigned URLs),
  ## the Lua expression evaluates to nil which Kong renders as empty string.
  ## The post-function strips this empty header so Storage's S3 signature
  ## verification falls through to query-parameter parsing.
  - name: storage-v1
    _comment: 'Storage: /storage/v1/* -> http://supabase-storage:5000/*'
    url: http://supabase-storage:5000/
    routes:
      - name: storage-v1-all
        strip_path: true
        paths:
          - /storage/v1/
    plugins:
      - name: cors
      - name: request-transformer
        config:
          add:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
          replace:
            headers:
              - "Authorization: $LUA_AUTH_EXPR"
      - name: post-function
        config:
          access:
            - |
              local auth = kong.request.get_header("authorization")
              if auth == nil or auth == "" or auth:find("^%s*$") then
                kong.service.request.clear_header("authorization")
              end

  ## Edge Functions routes
  - name: functions-v1
    _comment: 'Edge Functions: /functions/v1/* -> http://supabase-functions:9000/*'
    url: http://supabase-functions:9000/
    read_timeout: 150000
    routes:
      - name: functions-v1-all
        strip_path: true
        paths:
          - /functions/v1/
    plugins:
      - name: cors

  ## OAuth 2.0 Authorization Server Metadata (RFC 8414)
  - name: well-known-oauth
    _comment: 'Auth: /.well-known/oauth-authorization-server -> http://supabase-auth:9999/.well-known/oauth-authorization-server'
    url: http://supabase-auth:9999/.well-known/oauth-authorization-server
    routes:
      - name: well-known-oauth
        strip_path: true
        paths:
          - /.well-known/oauth-authorization-server
    plugins:
      - name: cors

  ## Analytics routes
  ## Not used - Studio and Vector talk directly to analytics via Docker networking.
  ## If external access is needed, add routes with key-auth matching Logflare's x-api-key auth.
  # - name: analytics-v1-api
  #   _comment: 'Analytics: /analytics/v1/api/endpoints/* -> http://logflare:4000/api/endpoints/*'
  #   url: http://supabase-analytics:4000/api/endpoints
  #   routes:
  #     - name: analytics-v1-api
  #       strip_path: true
  #       paths:
  #         - /analytics/v1/api/endpoints/
  # - name: analytics-v1
  #   _comment: 'Analytics: /analytics/v1/* -> http://logflare:4000/*'
  #   url: http://supabase-analytics:4000/
  #   routes:
  #     - name: dashboard-v1-all
  #       strip_path: true
  #       paths:
  #         - /analytics/v1
  #   plugins:
  #     - name: cors
  #     - name: basic-auth
  #       config:
  #         hide_credentials: true

  ## Secure Database routes
  - name: meta
    _comment: 'pg-meta: /pg/* -> http://pg-meta:8080/*'
    url: http://supabase-meta:8080/
    routes:
      - name: meta-all
        strip_path: true
        paths:
          - /pg/
    plugins:
      - name: key-auth
        config:
          hide_credentials: false
      - name: acl
        config:
          hide_groups_header: true
          allow:
            - admin

  ## Block access to /api/mcp
  - name: mcp-blocker
    _comment: 'Block direct access to /api/mcp'
    url: http://supabase-studio:3000/api/mcp
    routes:
      - name: mcp-blocker-route
        strip_path: true
        paths:
          - /api/mcp
    plugins:
      - name: request-termination
        config:
          status_code: 403
          message: "Access is forbidden."

  ## MCP endpoint - local access
  - name: mcp
    _comment: 'MCP: /mcp -> http://supabase-studio:3000/api/mcp (local access)'
    url: http://supabase-studio:3000/api/mcp
    routes:
      - name: mcp
        strip_path: true
        paths:
          - /mcp
    plugins:
      # Block access to /mcp by default
      - name: request-termination
        config:
          status_code: 403
          message: "Access is forbidden."
      # Enable local access (danger zone!)
      # 1. Comment out the 'request-termination' section above
      # 2. Uncomment the entire section below, including 'deny'
      # 3. Add your local IPs to the 'allow' list
      #- name: cors
      #- name: ip-restriction
      #  config:
      #    allow:
      #      - 127.0.0.1
      #      - ::1
      #    deny: []

  ## Protected Dashboard - catch all remaining routes
  - name: dashboard
    _comment: 'Studio: /* -> http://supabase-studio:3000/*'
    url: http://supabase-studio:3000/
    routes:
      - name: dashboard-all
        strip_path: true
        paths:
          - /
    plugins:
      - name: cors
      - name: basic-auth
        config:
          hide_credentials: true