Border Patrol is a type-safe, immutable, functional Scala library built on top of Finagle that provides modular components useful for session management and authentication. This library is used at Lookout for single sign on with support for multiple authentication backends.
The original version (as a server) can be found here (nginx+lua): ngx_borderpatrol
- The Border Patrol fronts all services (configured using
ServiceIdentifier
) in a Cloud. - The Cloud is identified by one or more subdomains (configured using
CustomerIdentifier
) - The Cloud, typically, has an identity
endpoint
(for authentication) and accessendpoint
(for authorization). - The identity endpoint, access endpoint, subdomains and default service forms the policy, which is defined using
LoginManager
. - When a HTTP request with URL
<http[s]>://<subdomain>:[port]/<path-prefix>
hits BorderPatrol:- It can check whether or not a host specified is supported by this instance of BorderPatrol.
- It looks up the CustomerIdentifier using subdomain prefix. It returns 404, if no match is found.
- It looks up the ServiceIdentifier using path prefix. In the absence of any path (i.e. Root), the request is redirected to the default service.
- Service Identifier:
- A service can be configured as protected (default) or unprotected.
- Once authenticated, the user has access to all the protected services in the Cloud
- The user (authenticated or not) has access to all the unprotected services in the Cloud
- A service identifier is comprised of a "unique"
/path
located on an upstream[hosts]
in the Cloud. - The Service path is mapped onto the subdomain that Border Patrol represents.
- Endpoint:
- An endpoint is represented by set of URLs and a unique path.
- Border Patrol connects to these remote REST endpoints fetches information or execute operations such as identity provisioning (i.e. identity endpoint), access issuing (i.e. access endpoint), authorization (external endpoint that does identity provisioning), token issuing (i.e. issues token for oauth2 code), etc.
- Identity Endpoint:
- If external authentication (e.g. OAuth2) is used, then identity endpoint provisions the user in Cloud.
- Currently, there are 2 identity provider service chains available for
tokenmaster.basic
andtokenmaster.oauth2
. - The
tokenmaster.basic
chain simply sends the user credentials to an identity endpoint in the Cloud. - The
tokenmaster.oauth2
chain redirects the user to authorization endpoint, with instructions to return the oauth2 code after authentication. The user authenticates with oauth2 server and oauth2 server returns oauth2 code (via browser redirect) to Border Patrol. The BorderPatrol user token endpoint to convert oauth2 code into access token. The Border Patrol fetches certificate from certificate endpoint and verifies the access token. The Border Patrol uses triple of subject, login manager name and subdomain to authenticate the user to identity endpoint. - The identity endpoint responds with a Master Token. The Master Token is cached in the Session.
- The implementation is modular and new service chains can easily be added
- Access Endpoint:
tokenmaster.basic
andtokenmaster.oauth2
use the same access service chain. It sends service name and Master Token to the access endpoint in the Cloud. That responds with a Service Token.- The Service Token is cached in the Session.
- The implementation is modular and new service chains can easily be added
- It relays Request w/ Service Token to the upstream endpoints, so that it can validate it.
- Session Store:
- A store is used to cache information about a Session.
- A SessionId (a signed id with an expiry) acts a key to the session. The SessionId is sent to the user as a cookie in the HTTP response.
- For unauthenticated user, the Session contains original Request
- For authenticate user, the Session contains Master Token and one or more Service Token(s)
- Secret Store:
- A store is used to cache secret used to sign the session id(s)
- Host Checker:
- A filter that blocks any request with a host entry that is not present in the
allowedDomains
entry. If request does not contain host header, this filter is a noop. This filter is applied by default and the config will throw an exception if there is no entry/0 entries for this field. The code should be updated if you don't intend on using it.
- A filter that blocks any request with a host entry that is not present in the
-
secretStore
: Secret Store. It can be configured usingtype
asInMemorySecretStore
orConsulSecretStore
.-
InMemorySecretStore
: Typically used for single host setup as Secrets are meant to be shared across all the BorderPatrol nodes."secretStore" : { "type" : "InMemorySecretStore", }
-
ConsulSecretStore
: Setting up Consul is outside of the scope.hosts
: A list of consul URLs (Format:[<http[s]>://<host>:[port]]+
)key
: BorderPatrol uses the key-value store for storing the secret. Thekey
is configurable.
"secretStore" : { "type" : "ConsulSecretStore", "hosts": ["http://localhost:8500"], "key": "BpSecrets" }
-
-
sessionStore
: Session Store. It can be configured usingtype
asInMemoryStore
orMemcachedStore
.-
InMemoryStore
: Typically used for single host setup as Sessions are meant to be shared across all the BorderPatrol nodes."sessionStore" : { "type" : "InMemoryStore", }
-
MemcachedStore
: Setting up Memcached is outside of the scope. BorderPatrol uses it to store Sessions.hosts
: A comma separated list of of memcached host and port (Format:<host>:[port],<host>:[port]
)
"sessionStore" : { "type" : "MemcachedStore", "hosts" : "localhost:123,localhost:234" }
-
-
endpoints
: A list ofendpoint
s. -
endpoint
:hosts
: A list of endpoint URLs (Format:[<http[s]>://<host>:[port]]+
)path
: A path serviced by the endpoint.name
: A unique name that identifies this endpoint
-
loginManagers
: A list of LOGINManager
s -
loginManager
: It defines policy items such as authentication backend, identity endpoint, access endpoint, etc used for the given CustomerIdentifier.name
: unique name that identifies this Login Managerguid
: the global UID for the login manageridentityEndpoint
: Identity endpoint name used by this Login ManageraccessEndpoint
: Access endpoint used by this Login ManagerloginConfirm
: The path at whichInternal
login form or external authenticator posts the login credentialstype
: The type of proto used. Currently supported types aretokenmaster.basic
andtokenmaster.oauth2
tokenmaster.basic
specific config:authorizePath
: A path to request login form
tokenmaster.oauth2
specific config:authorizeEndpoint
: An endpoint to request an authorization code for access to a resourcetokenEndpoint
: An endpoint to request access token using authorization codecertificateEndpoint
: An endpoint to fetch certificate to verify token signatureclientId
: Client id of the OAuth2 server applicationclientSecret
: Client secret of the OAuth2 server application
-
serviceIdentifiers
: A list of services in the cloud. -
serviceIdentifier
: A service.hosts
: A list of service URLs (Format:[<http[s]>://<host>:[port]]+
)name
: A unique name that identifies this Service. For protected services, the access issuer must be aware of this servicepath
: A path serviced by the service, which is mapped on the subdomain.rewritePath
: If configured, this path replaces thepath
in the incoming Requestprotected
: If the service is NOT protected, then it bypasses access issuer. The default istrue
.
-
customerIdentifiers
: A list of customer identifiers. -
customerIdentifier
:loginManager
: Login Manager or policy used by this customer identifierguid
: the global UID for the subdomainsubdomain
: A subdomain represented by this identifierdefaultServiceIdentifier
: The default "protected" service for this customer identifier
-
statdReporter
: The statsd reporter configurationhost
: Upstream statsd endpointdurationInSec
: Reporting frequency in Seconds.prefix
: Prefix attached to each reported stat
-
listeningPort
: Border Patrol listens to new requests on this port. -
healthCheckEndpoints
: A set of endpoints that impact the Border Patrol Health Status -
allowedDomains
: Border Patrol checks whether incoming request has a host header value present in this set."allowedDomains" : [ "api.localhost", "ent.localhost"],
- If the domain name is "example.com"
"allowedDomains" : [ "api.example.com", "ent.example.com"],
Border Patrol uses a multi-project structure and contains the following modules:
core
- the core classes/functionsauth
- different authentication plugins for core authsecurity
- different security plugins, e.g. CSRF protectionserver
- a server composing these modules that can be configuredexample
- the demo app showing sessions and authentication for multiple services. It mocks the authentication (aka identity provider), authorization (aka access issuer) and upstream endpoints.
Every stable Border Patrol module is published at Bintray. The SNAPSHOT builds are published to JFrog.
- stable release:
libraryDependencies ++= Seq(
"com.lookout.borderpatrol" %% "[borderpatrol-module]" % "0.2.0"
)
SNAPSHOT
release:
libraryDependencies ++= Seq(
"com.lookout.borderpatrol" %% "[borderpatrol-module]" % "0.2.10-SNAPSHOT"
)
To build Border Patrol you should have sbt
installed (prefer v0.13.8+). Run sbt
, and then use any of the following commands:
compile
: compile the codeproject [project]
: to switch projects, e.g. "project example"console
: launch a REPLtest
: run the testsunidoc
: generate the documentationscalastyle
: run the style-checker on the codevalidate
: run tests, style-checker, and doc generation
-
To test and work with subdomain routing locally, ensure to update your /etc/hosts file to include subdomains to localhost. For example:
127.0.0.1 ent.localhost
-
Run
$ sbt > project example > run
- Scaladoc is available at http://lookout.github.io/borderpatrol/docs
- Markdown documents are available here. The code examples are fully runnable in a Scala REPL verified with tut. Use
sbt tut
to compile example code in markdown (docs/src/main/tut
) which outputs totarget/scala-N.NN/tut
We would love to make this better, so please help us!
- Submit a PR including an issue label "easy"
- Write ScalaDoc comments
- Write tutorials and examples
- Improve tests
- Help with code review
- Give it a star
- Join us on IRC
#borderpatrol
on Freenode
We use the MIT License License