Giter Site home page Giter Site logo

portier / portier-broker Goto Github PK

View Code? Open in Web Editor NEW
549.0 17.0 17.0 2.25 MB

Portier Broker reference implementation, written in Rust

Home Page: http://portier.github.io/

License: Apache License 2.0

Rust 87.66% JavaScript 0.33% CSS 0.27% Dockerfile 0.41% Shell 0.57% TypeScript 5.78% Mustache 1.14% Jinja 3.18% Procfile 0.01% Nix 0.64%
portier auth rust openidconnect

portier-broker's Introduction

Portier Broker

This is the Portier Broker reference implementation.

How to run your own broker

HerokuDeploy

Portier is specified such that everyone can run their own broker instance. You can point your Relying Parties at your own broker, so that you do not have to depend on the broker run by the Portier project.

Binaries for the broker can be found on the GitHub releases page. Docker images are also available on Docker Hub. Alternatively, you can build the broker yourself.

The broker can be configured using a configuration file or through environment variables. Both are documented in the example configuration file.

Once you've prepared the configuration, simply run the broker executable:

# From binaries:
./portier-broker[.exe] ./config.toml

# Using Docker:
docker run -v /srv/portier-broker:/data:ro portier/broker /data/config.toml

Some additional notes:

  • If using environment variables only, don't specify a configuration file on the command line.

  • Systemd units are also included with the Linux binaries.

  • The broker only talks plain HTTP, and not HTTPS. Using HTTPS is strongly recommended, but you'll need to add a reverse proxy in front of the broker to do this. (Apache or Nginx can do this for you.)

portier-broker's People

Contributors

callahad avatar colemickens avatar dependabot[bot] avatar djc avatar dstaley avatar eallrich avatar github-actions[bot] avatar jimdigriz avatar jvasseur avatar onli avatar r-stephank avatar skorokithakis avatar stephank 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  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

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

portier-broker's Issues

Check Cargo.lock into the repo

We need to be absolutely certain that the binary is consistently built with the same dependent libraries to avoid inconsistencies and regressions on bugs like #28

README.md

The Broker needs a README that explains:

  • Its exposed API surface (HTTP routes and methods)
  • How to interact with it (which will likely form the basis of a future, general Using Portier doc on the main site)
  • How to develop it locally
  • How to deploy it in production

I'd especially love it if the document discussed deploying on Heroku or a similar PaaS's free tier, to facilitate hobbyists who want to self-host.

Send Cache-Control header in response

We should add the Cache-Control headers to our responses.

  • Login routes: no-cache, no-store.
  • Discovery document and other static resources: public, max-age=86400 (1 day)
  • Keys document should be public, with a configurable age. This depends on how often keys are rotated.
  • /.well-known, probably no-cache?

Refactor to provider selection to be more modular

Our level of abstraction doesn't feel right yet. Our current code basically functions as:

  1. If email.domain in providers:
    1. Get a redirect URL from the openid module
    2. Redirect the user
  2. Else:
    1. Get a session ID from the email module
    2. Display the confirm email template to the user

I don't think this is the best solution in a few areas:

  • It only switches on email domain. As per #44, we might want to switch on other attributes in the future.
  • If two domains are serviced by the same provider, as is the case with gmail.com and googlemail.com we have to duplicate that in the configuration.
  • General OIDC and Gmail-specific rules are commingled in src/oidc.rs
  • This design presumes that all providers are OIDC providers.
  • The returned values aren't unified: you get either a URL or a session ID.
  • The redirect logic is split between the individual module and src/lib.rs.

I'm not sure how to best address this, but I think the answer might be along the lines of:

  • All providers adhere to a common interface or implement a common trait
  • Providers completely handle incoming requests and return a ready-to-use iron::Response
  • Split the generic OIDC provider and the Gmail provider into separate modules. The Gmail one can, of course, rely on facilities offered by the generic one.
  • Providers can return whether or not they can handle an address, either through a function returning bool, or by returning an Option<Iron::Response>.
  • We keep a prioritized list of providers, and just iterate over it, trying each one until one succeeds.

Cache OIDC provider keys

Similar to #6, it could be helpful to cache the public key data from the OIDC providers for a while. Probably use the key ID in the store key to make things easy.

Set X-Frame-Options: Deny and/or Immediately Revoke Google Credentials

Problem: After completing the Gmail flow, future logins do not require any user interaction. This could be dangerous.

We tried using ?prompt=consent (#76) to require reconfirmation, but it shows an alarming message to users (#80), so we can't do that.

Stack Overflow suggests that we could solve this by immediately revoking our access immediately after validating a token (#84).

It seems like we have three options:

  1. Prompt on every login by immediately revoking our access token (#84)
  2. Prompt on every login in the broker, before redirecting back to the RP.
  3. Do not prompt on every login

The second option seems like over-engineering for now. So, do we want to prompt on every login or not? What attack are we actually trying to protect against?

Cache OIDC provider metadata

Can cache the bits of the discovery document we use in Redis. Probably makes sense to just cache with a 3600s expiry, rather than doing complicated ETag and Last-Modified handling? The Google IdP sets timeout of an hour explicitly, though Microsoft doesn't send anything like it.

Bump DMARC policy to p=quarantine or p=reject

Right now our DMARC record is set to p=none. It looks like it's working, and I can't imagine anything else sending mail from our domain, so we should be able to bump it to a more restrictive policy soon.

Revisit in mid-November, once we have a few weeks of running the broker in production under our belts.

Allow setting SMTP credentials

We currently only support unauthenticated SMTP connections, which is fine if access control is done some other way. (E.g. mailserver only listens on localhost, or is strictly firewalled.)

For AWS SES or other cloud mail services, we need to provide credentials and support STARTTLS.

Make it aesthetically pleasing

The error pages, interstitials, emails, and such should look like a modern web application

Yes, this means HTML email. :(

Detect G Suite domains

Currently, it's possible to get the oidc flow for a G Suite domain by simply copying the provider section for gmail.com for each domain you want. It'd be neat if we could detect domains that run mail through G Suite.

Is checking MX records enough? This was on the backlog for Persona, so I'm not sure what their findings and experiences are, but that would be valuable to look into.

We need an icon

Both for favicon and Google auth screen reasons. Compare:

screenshot from 2016-10-26 16-19-13


screenshot from 2016-10-26 16-23-13

Audit library licenses

We're claiming to license this program as MIT/Apache2. Can we actually do that? Are we sure none of our dependencies (or their dependencies) are GPL'd?

Reconsider degree of configurability

Do we really need:

  • crypto.token_ttl
  • redis.session_ttl
  • redis.cache_ttl
  • redis.cache_max_doc_size

The TTLs all seem like things we can/should take an opinionated stance on, and the max document size in the Redis cache seems of questionable utility.

Move onto Heroku

We need to be on some kind of managed, horizontally-scalable PaaS before launch.

Enable continuous delivery on Heroku?

I'd like it if any merge to master automatically deployed to Heroku. I've set this up for the Demo RP, and it works great.

Environment variables persist across deployments and Redis is kept separate, so there's no other state we need to worry about preserving.

Add Clippy as a build hook

Clippy has nice lints. We should integrate it with our build process. We should be able to roll this into Travis.

Expose version metadata somewhere

We should be able to discover what version of our software the broker is running.

On Heroku, with Dyno Metadata enabled, we can use the HEROKU_SLUG_COMMIT envvar to get the hash for the running broker. We should expose that.

Improve logging and metrics

Right now we have almost no visibility into the ongoing health and failure rates of this service.

We should make heavy use of our logging facilities, consider setting up some kind of log aggregation and error reporting service, and get some sort of statsd-style metrics going.

Use templates for the email message.

From a TODO in the code:

// on localhost. TODO: Use templates for the email message.

Compile-time or run-time?

Run-time of course means more files (right now just the binary and config), but also more configurability without a rebuild. For run-time, I'm leaning towards liquid.

But compile-time may be good enough for us, considering the primary goal is a central hosted service.

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.