# Authx - Proof of Concept This repository explores various authentication and authorization workflows by introducing a separate authn/authz service. It serves as a proof of concept to illustrate potential workflows, not a production ready implementation. To keep the implementation accessible, external dependencies have been minimized, ensuring a clear reference for understanding key concepts, including: * SAML based authentication including IdP chaining to external identity providers * OIDC based authentication * OAuth endpoints with links to relevant RFCs for proper usage guidance Below is a recording of a SAML based service provider initiated login, displaying raw SAML XML to illustrate each step of the workflow. ![SAML Login](./screencast.webm) ## Architecture ```plaintext ------------- | user-agent | ------------- | V ----|:8080|----------------------------------------------- | V --------------- | API Gateway | (use casbin to evict early) --------------- | (reverse proxy and injects context headers) | ----- | -------------------- (_____) |--->| IdP (saml, oidc) |----->| db | | | | ----- | -------------------- | | :http | :grpc | (use declarative_policy) | -------------------- | A ----------- | | | | V V | ------ ------------ | | UI | | REST API |----| ------ ------------ [UI]: ui.example.com [REST API]: api.example.com [IdP]: idp.example.com ``` I have ommitted TLS, RS256 from the prototype to offload the decision of key management and rotation. See [smallstep](https://smallstep.com/docs/step-cli/) for PKI management. ## Getting Started 1. Install tools: ```sh $ mise install ``` 1. Add entries to `/etc/hosts`: ```sh $ tail -n3 /etc/hosts 127.0.0.1 api.example.com 127.0.0.1 idp.example.com 127.0.0.1 ui.example.com ``` 1. Start servers: ```sh $ mage ``` 1. Open browser to `http://ui.example.com:8080/saml/new` to start a new SAML session. Or open `http://ui.example.com:8080/oidc/new` to start a new OIDC session. ## Experiments ### Twirp + gRPC (AuthZ) This experiment exposes a gRPC endpoint that aligns with the [`Ability.allowed?(subject, permission, resource)`][1] interface from GitLab's declarative authorization logic. It demonstrates a headless authorization service that provides a low-latency decision point for other services to verify permissions. Actors in this experiment: * Headless authz service: A facade over GitLab’s existing declarative policies. * API (Resource Server in OAuth terms): A slimmed-down GitLab REST API that delegates authorization decisions to the authz service. ### SAML, OIDC, OAuth This experiment showcases how a separate authx service can handle both authentication and authorization using standard protocols: * SAML & OIDC for authentication * OAuth for authorization Actors in this experiment: * Authx service: Acts as a SAML Identity Provider and an OAuth Authorization Server. * API: A slimmed-down GitLab REST API. ### API Gateway This experiment explores a stateless authorization mechanism by integrating a policy DSL (such as [Casbin][3]) into a reverse proxy. Authorization decisions are made early in the request pipeline based on HTTP request headers and body content. ### Sidecar Process This experiment demonstrates a sidecar approach for making authorization decisions within an nginx process. Inspired by [Open Policy Agent][4] deployments. This experiment: * Uses lua bindings in nginx to connect to a local client process. * The client process proxies requests to a gRPC based policy decision service. ## Questions 1. What is the unique identifier for each security principal across service boundaries? (i.e. bigint, ulid, uuid, email) ## References * [go tool][5] * [gRPC][6] * [protocol buffers][7] * [twirp][8] [1]: https://gitlab.com/gitlab-org/gitlab/-/blob/e1f6db024561e35462ac8d9f54b8f9678f6ed6ee/app/models/ability.rb#L73 [2]: https://gitlab.com/gitlab-org/gitlab/-/tree/master/app/policies [3]: https://casbin.org/ [4]: https://www.openpolicyagent.org/ [5]: https://tip.golang.org/doc/modules/managing-dependencies#tools [6]: https://grpc.io/docs/ [7]: https://protobuf.dev/programming-guides/proto3/ [8]: https://github.com/arthurnn/twirp-ruby/wiki/Code-Generation