Coder Social home page Coder Social logo

imkira / gcp-iap-auth Goto Github PK

View Code? Open in Web Editor NEW
87.0 7.0 31.0 108 KB

A simple server implementation and package in Go for helping you secure your web apps running on GCP behind a Cloud IAP (Identity-Aware Proxy)

License: MIT License

Makefile 6.21% Go 90.85% Dockerfile 2.94%
golang google cloud gcp iap proxy nginx auth kubernetes jwt

gcp-iap-auth's Introduction

gcp-iap-auth

License Build Status

gcp-iap-auth is a simple server implementation and package in Go for helping you secure your web apps running on GCP behind a Google Cloud Platform's IAP (Identity-Aware Proxy) by validating IAP signed headers in the requests.

Why

Validating signed headers helps you protect your app from the following kinds of risks:

  • IAP is accidentally disabled;
  • Misconfigured firewalls;
  • Access from within the project.

How to use it as a package

go get -u github.com/imkira/gcp-iap-auth/jwt

The following is just an excerpt of the provided simple.go example:

// Here we validate the tokens in all requests going to
// our server at http://127.0.0.1:12345/auth
// For valid tokens we return 200, otherwise 401.
func AuthHandler(w http.ResponseWriter, req *http.Request) {
	if err := jwt.ValidateRequestClaims(req, cfg); err != nil {
		w.WriteHeader(http.StatusUnauthorized)
	} else {
		w.WriteHeader(http.StatusOK)
	}
}

For advanced usage, make sure to check the available documentation here.

How to use it as a server

Binary Releases are provided for convenience.

After downloading it, you can execute it like:

gcp-iap-auth --audiences=YOUR_AUDIENCE

Construction of the YOUR_AUDIENCE string is covered here

HTTPS is also supported. Just make sure you give it the cert/key files:

gcp-iap-auth --audiences=YOUR_AUDIENCE --tls-cert=PATH_TO_CERT_FILE --tls-key=PATH_TO_KEY_FILE

It is also possible to use environment variables instead of flags. Just prepend GCP_IAP_AUTH_ to the flag name (in CAPS and with - replaced by _) and you're good to go (eg: GCP_IAP_AUTH_AUDIENCES replaces --audiences)

For help, just check usage:

gcp-iap-auth --help

How to use it as a reverse proxy

In this mode the gcp-iap-auth server runs as a proxy in front of another web app. The JWT header will be checked and requests with a valid header will be passed to the backend, while all other requests will return HTTP error 401.

gcp-iap-auth --audiences=YOUR_AUDIENCE --backend=http://localhost:8080

In proxy mode you may optionally specify a header that will be filled with the validated email address from the JWT token. The value will only contain the email address, eg: [email protected], unlike the x-goog-authenticated-user-email header this does not contain a namespace prefix, making this approach suitable for backend apps which only want an email address.

gcp-iap-auth --audiences=YOUR_AUDIENCE --backend=http://localhost:8080 --email-header=X-WEBAUTH-USER

Integration with NGINX

You can also integrate gcp-iap-auth server with NGINX using the http_auth_request_module.

The important part is as follows (full nginx.conf example file here):

    upstream AUTH_SERVER_UPSTREAM {
      server AUTH_SERVER_ADDR:AUTH_SERVER_PORT;
    }

    upstream APP_SERVER_UPSTREAM {
      server APP_SERVER_ADDR:APP_SERVER_PORT;
    }

    server {
      server_name APP_DOMAIN;

      location = /gcp-iap-auth {
          internal;
          proxy_pass                 http://AUTH_SERVER_UPSTREAM/auth;
          proxy_pass_request_body    off;
          proxy_pass_request_headers off;
          proxy_set_header           X-Goog-IAP-JWT-Assertion $http_x_goog_iap_jwt_assertion;
      }

      location / {
        auth_request /gcp-iap-auth;
        proxy_pass   http://APP_SERVER_UPSTREAM;
      }
    }

Please note:

  • Replace AUTH_SERVER_UPSTREAM, AUTH_SERVER_ADDR, and AUTH_SERVER_PORT with the data about your gcp-iap-auth server.
  • Replace APP_SERVER_UPSTREAM, APP_SERVER_ADDR, and APP_SERVER_PORT with the data about your own web app server.
  • Replace APP_DOMAIN with the domain(s) you set up in your GCP IAP settings.
  • gcp-iap-auth only needs to receive the original X-Goog-IAP-JWT-Assertion header sent by Google, so you can and you are advised to disable proxying the original request body and other headers. Not only it is unecessary you may leak information you may not want to.
  • Please adjust appropriately (you may want to use HTTPS instead of HTTP, multiple domains, etc.). This example is just provided for reference.

Using it with Docker

Docker images are provided for convenience.

docker run --rm -e GCP_IAP_AUTH_AUDIENCES=YOUR_AUDIENCE imkira/gcp-iap-auth

For advanced usage, please read the instructions inside.

Using it with Kubernetes

As a reverse proxy

A simple way to use it with kubernetes and without any other dependencies is to run it as a reverse proxy that validates and forwards requests to a backend server.

      - name: gcp-iap-auth
        image: imkira/gcp-iap-auth:0.0.5
        env:
        - name: GCP_IAP_AUTH_AUDIENCES
          value: "YOUR_AUDIENCE"
        - name: GCP_IAP_AUTH_LISTEN_PORT
          value: "1080"
        - name: GCP_IAP_AUTH_BACKEND
          value: "http://YOUR_BACKEND_SERVER"
        ports:
        - name: proxy
          containerPort: 1080
        readinessProbe:
          httpGet:
            path: /healthz
            scheme: HTTP
            port: proxy
          periodSeconds: 1
          timeoutSeconds: 1
          successThreshold: 1
          failureThreshold: 10
        livenessProbe:
          httpGet:
            path: /healthz
            scheme: HTTP
            port: proxy
          timeoutSeconds: 5
          initialDelaySeconds: 10

With NGINX

You can use it with kubernetes in different ways, but I personally recommend running it as a sidecar container by adding it to, say, an existing NGINX container:

      - name: nginx
      # your nginx container should go here...
      - name: gcp-iap-auth
        image: imkira/gcp-iap-auth:0.0.5
        env:
        - name: GCP_IAP_AUTH_AUDIENCES
          value: "YOUR_AUDIENCE"
        - name: GCP_IAP_AUTH_LISTEN_PORT
          value: "1080"
        ports:
        - name: auth
          containerPort: 1080
        readinessProbe:
          httpGet:
            path: /healthz
            scheme: HTTP
            port: auth
          periodSeconds: 1
          timeoutSeconds: 1
          successThreshold: 1
          failureThreshold: 10
        livenessProbe:
          httpGet:
            path: /healthz
            scheme: HTTP
            port: auth
          timeoutSeconds: 5
          initialDelaySeconds: 10

Notes

To use HTTPS just make sure:

  • You set up GCP_IAP_AUTH_TLS_CERT=/path/to/tls_cert_file and GCP_IAP_AUTH_TLS_KEY=/path/to/tls_key_file environment variables.
  • You set up volumes for secrets in kubernetes so it knows where to find them.
  • Change the scheme in readiness and liveness probes to HTTPS.
  • Adjust your nginx.conf as necessary to proxy pass the auth requests to gcp-iap-auth as HTTPS.

License

gcp-iap-auth is licensed under the MIT license:

www.opensource.org/licenses/MIT

Copyright

Copyright (c) 2017 Mario Freitas. See LICENSE for further details.

gcp-iap-auth's People

Contributors

abstrctn avatar biggestt avatar imkira avatar joemiller avatar neuroid avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

gcp-iap-auth's Issues

proxy mode

I would like to use gcp-iap-auth as a proxy in front of other webapps: [iap] -> [gcp-iap-auth] -> [backend app]. Assuming this will work. I started working on a small utility to do this and realized I was importing so much of gcp-iap-auth that maybe it would make sense to implement proxy-mode as an option, perhaps a flag like -proxy http://localhost:8080.

I am happy to send a PR, time permitting, if you think this may be acceptable?

No public key

Hi,

my instance of gcp-iap-proxy stopped working. All authentications failed and log was full of Failed to authenticate "[email protected]" (No public key for "2nMJtw"). Restart solved the issue.

I guess that public keys are loaded once when process starts. If Google changes them, restart is necessary.

Feature Request: add username header

n proxy mode we can specify a header that will be filled with the validated email address from the JWT token. The value will only contain the email address, eg: [email protected]:

gcp-iap-auth --audiences=YOUR_AUDIENCE --backend=http://localhost:8080 --email-header=X-WEBAUTH-USER

Can we have another header just to provide username? eg: name from [email protected] using --name-header=X-WEBAUTH-NAME

Make a new release

The current release is not compatible with IAP because it's looking for the wrong header. This was fixed in 91f16a3.

Users of package managers that pull down a release will be pulling a broken version of this package until a new release is created.

keepalive

When running in reverse proxy mode, how does gcp-iap-auth handle keepalive at downstream and upstream? Will it disconnect after every request or re-use the connection? If latter, what is the idle timeout and will it honor "Connection: close" or other keepalive related http headers?

FR: proxy mode guest access

When running gcp-iap-auth in proxy mode, it would be great to let the traffic through, not giving 401, in case when the jwt can't be validated or doesn't exist. This will allow backend application to provide the guest content or secondary login option.

In such cases, the gcp-iap-auth should clear the bad jwt header, and also clear the email-header, etc. to prevent clients from spoofing the login. The backend can then trust the email-header to decide if it is authenticated request or anonymous request.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.