Skip to content

Latest commit

 

History

History
323 lines (275 loc) · 11.3 KB

README.md

File metadata and controls

323 lines (275 loc) · 11.3 KB

Controlling and managing access to your API endpoints

There are several ways you can use to protect your API endpoints. While supporting built-in authentication mechanisms and other access restriction methods are in the project roadmap, these features are not yet implemented. We recommend that you consider one of the following strategies depending on your deployment model and requirements: you can use an existing cloud service, deploy a reverse proxy server like Envoy / NGINX or use a service mesh ingress controller like Istio Gateway.

Using a cloud service

Cloud providers offer API gateway services that can help you manage access to your GraphQL API. For example: Amazon API Gateway, Google Cloud Endpoints and Azure API Management

API gateway services allow you to control access to your API endpoints by restricting access to selected VPCs and accounts.

Example: Creating a private API in Amazon API Gateway

Deploy the GraphQL endpoint on a Virtual Private Cloud (VPC) subnet, within the same VPC as the Apache Cassandra nodes or within a peered VPC. Make sure you only allow ingress from desired CIDR blocks to the security group. Also, don't associate public IP addresses to the endpoint.

Create a private Amazon API Gateway that can only be accessed from your virtual private cloud by assigning the VPC endpoint id(s). Next, create a child resource, marking it as a "proxy resource", set up integration type as HTTP proxy and enter the endpoint URL.

You can now control access to your API Gateway by managing the subnets and security groups for the VPC endpoint.

Using a reverse proxy server

You can use a L7 proxy server like Envoy or NGINX to delegate access control and http connection management, allowing you to place your GraphQL API instance under a private subnet. You can then protect your proxy instance with http filters, integrating it with your own authorization mechanisms.

Example: Setup Envoy

Envoy can be used to control access to the data APIs using an external authentication service, JSON Web Tokens (JWT), or TLS client certificates.

Start with basic proxy forwarding:

static_resources:
  listeners:
  - name: listener0
    address:
      socket_address: { address: 0.0.0.0, port_value: 10000 }
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          stat_prefix: ingress_http
          codec_type: AUTO
          route_config:
            name: local_route
            virtual_hosts:
            - name: cassandra_apis
              domains: ["*"]
              routes:
              - match: { prefix: "/" }
                route: { cluster: cassandra_apis }
          http_filters:
          - name: envoy.filters.http.router

  clusters:
  - name: cassandra_apis
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: cassandra_apis
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8080

External Authentication

External authentication forwards a subrequest with select headers to the external service for validation. More information can be found in the Envoy external authentication documentation.

static_resources:
  listeners:
  - name: listener0
    # ...
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          # ...
          http_filters:
          - name: envoy.ext_authz
            typed_config:
              "@type": type.googleapis.com/envoy.config.filter.http.ext_authz.v2.ExtAuthz
              http_service:
                server_uri:
                  uri: 127.0.0.1:8081
                  cluster: your_auth_service
                  timeout: 0.25s
                authorization_request:
                  allowed_headers: 
                    patterns:
                      exact: "Authorization"
                      # ...
                authorization_response:
                  allowed_upstream_headers: 
                    patterns:
                      exact: "Authorization"
                      # ...
                  allowed_client_headers: 
                    patterns:
                      exact: "Authorization"
                      # ...
          - name: envoy.filters.http.router

  clusters:
  # ...
  - name: your_auth_service
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: your_auth_service
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8081

JSON Web Tokens (JWT)

JWT authentication validates JSON web tokens against keys provided by either a local file or a remote provider. More information can be found in the Envoy JWT documentation.

static_resources:
  listeners:
  - name: listener0
    # ...
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          # ...
          http_filters:
          - name: envoy.filters.http.jwt_authn
            typed_config: 
              "@type": type.googleapis.com/envoy.config.filter.http.jwt_authn.v2alpha.JwtAuthentication
              providers:
                auth0:
                  issuer: https://your-tokens-issuer.com/
                  audiences:
                  - https://your-services-url.com
                  remote_jwks:
                    http_uri:
                      uri: 127.0.0.1:8081
                      cluster: jwt_auth
                      timeout: 5s
                    cache_duration:
                      seconds: 300
          - name: envoy.filters.http.router

  clusters:
  # ...
  - name: jwt_auth
    connect_timeout: 0.25s
    type: STATIC
    lb_policy: ROUND_ROBIN
    load_assignment:
      cluster_name: jwt_auth
      endpoints:
      - lb_endpoints:
        - endpoint:
            address:
              socket_address:
                address: 127.0.0.1
                port_value: 8081

Client Certificates

Clients can be verified and authenticated server-side using TLS along with a certificate provided by the client. More information about enabling client certificates and TLS can be found in the Envoy documentation.

static_resources:
  listeners:
  - name: listener0
    # ...
    filter_chains:
    - filters:
      - name: envoy.filters.network.http_connection_manager
        typed_config:
          "@type": type.googleapis.com/envoy.config.filter.network.http_connection_manager.v2.HttpConnectionManager
          # ...
      tls_context:
        common_tls_context:
          require_client_certificate: true
          validation_context:
            trusted_ca:
              filename: "/path/to/ca.pem"
            verify_certificate_hash:
              # Hashes for authorized client certificates
              - "068ec9830b228c69869babd5c4c15e346d84dba17f414de0460bd0901b2ca8af"
              # ...
          tls_certificates:
            - certificate_chain:
                filename: "/path/to/cert.pem"
              private_key:
                filename: "/path/to/key.pem"

  clusters:
  # ...

Example: Setup NGNIX

NGNIX can also be used control access using either an external authentication service or TLS client certificates.

Start with basic proxy forwarding:

server {
    listen 10000;

    location / {
       proxy_pass http://127.0.0.1:8080/;
    }
}

External Authentication

External authentication forwards a subrequest with select headers to the external service for validation. More information can be found in the NGINX external authentication documentation.

server {
    listen 10000;

    location / {
       auth_request /auth;
       proxy_pass http://127.0.0.1:8080/;
    }

    # External authentication service
    location = /auth {
        internal;
        proxy_pass              http://127.0.0.1:8081;
        proxy_pass_request_body off;
        proxy_set_header        Content-Length "";
    }
}

Client Certificates

Clients can be verified and authenticated server-side using TLS along with a certificate provided by the client. More information about enabling client certificates and TLS can be found in the NGINX documentation.

server {
    listen 10000;

    ssl_certificate /path/to/cert.pem;
    ssl_certificate_key /path/to/key.pem;
    ssl_client_certificate /path/to/ca.pem;
    ssl_verify_client on

    location / {
       proxy_pass http://127.0.0.1:8080/;
    }
}

Using a service mesh ingress controller

If you are using a service mesh such as Istio or linkerd, consider the features that are provided by the ingress controller for that service mesh. For example, Istio Gateway lets you restrict access to a set of virtual services that can bind to a server like explained in this documentation.