Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

add JAAS security doc #62

Merged
merged 5 commits into from
Oct 8, 2024
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions .custom_wordlist.txt
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ Charmhub
CLI
CN
config
CORS
Diátaxis
DNS
dropdown
Expand All @@ -24,6 +25,7 @@ GitHub
Google
Grafana
HAProxy
HMAC
https
IAM
IdP
Expand All @@ -36,6 +38,9 @@ JSON
juju
Juju
Juju's
JWKS
JWT
JWTs
K8s
Keystore
Kratos
Expand Down Expand Up @@ -85,6 +90,7 @@ ReBAC
reST
reStructuredText
roadmap
RSA
RTD
Skype
Snapcraft
Expand All @@ -108,4 +114,5 @@ VMs
webhook
Websocket
Xbox
XSRF
YAML
4 changes: 4 additions & 0 deletions .wordlist.txt
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
addmodel
addons
auth
authenticy
API
APIs
balancer
Charmhub
cryptographic
cryptographically
CLI
Diátaxis
dropdown
Expand Down
5 changes: 5 additions & 0 deletions explanation/jaas_security_scope.rst
Original file line number Diff line number Diff line change
@@ -1,6 +1,11 @@
JAAS Security Scope
===================

..
TODO (Kian):
Much of this document's content is now covered in the security doc in reference/security and reused where possible.
We should consider what parts of this doc to remove and where to better put the parts that we keep.

The scope of JAAS' security covers multiple aspects, including:

Secure Communication
Expand Down
10 changes: 9 additions & 1 deletion reference/index.rst
Original file line number Diff line number Diff line change
@@ -1,7 +1,15 @@
Reference
=========

**Technical information** - specifications, APIs, and reference docs.
**Technical information** - security, APIs, and reference docs.

Security
--------

.. toctree::
:maxdepth: 1

JAAS Security <security>

.. toctree::
:maxdepth: 1
Expand Down
291 changes: 291 additions & 0 deletions reference/security.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,291 @@
JAAS Security
=============

This document is an overview of JAAS specifically covering areas pertaining to security and/or sensitive data.

In each section we explain how the information is stored/transmitted and any cryptographic
technologies used.

Cloud-Credentials
-----------------

Cloud-credentials are the API keys Juju/JAAS needs in order to provision cloud infrastructure.
These keys are uploaded to and stored by JAAS. Whenever a a model is created, the key is uploaded to
kian99 marked this conversation as resolved.
Show resolved Hide resolved
the Juju controller and used to manage cloud resources.

User provided cloud credentials are stored securely and safely within a secret `vault <https://www.vaultproject.io/>`__.
kian99 marked this conversation as resolved.
Show resolved Hide resolved
It is essential to handle these secrets securely to prevent unauthorised access and data breaches
kian99 marked this conversation as resolved.
Show resolved Hide resolved
to the user's cloud.

The use of Vault ensures that credentials are encrypted at rest and provides tools to avoid unauthorised
access.

JAAS - Juju Communication
--------------------------

JAAS acts as a central auth gateway between users and Juju controllers.
Juju controllers explicitly trust JAAS by setting the ``login-token-refresh-url`` at bootstrap
kian99 marked this conversation as resolved.
Show resolved Hide resolved
time. See our :doc:`how-to <../how-to/add_controller>` for more info on how to setup a new
Juju controller for JAAS.

Trust between Juju controllers and JAAS is established through the use of asymmetric cryptography
and `JSON Web Tokens <https://jwt.io/introduction>`__ (JWT).

.. hint::

To avoid confusion, note that JWTs are also used elsewhere in JAAS particularly in user sessions.
Although solving a similar problem, the tokens used between JAAS and Juju and those issued to users
are two separate systems.

The ``login-token-refresh-url`` config option points to a
`JSON Web Key Set <https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets>`__
(JWKS) endpoint. This endpoint contains a set of public keys used to verify the authenticy of tokens
issued by JAAS.

Whenever a request is made by JAAS to a Juju controller, a JWT is issued that encodes the user's
information and permissions. This mechanism allows the authorisation and authentication to be securely
delegated from the Juju controller to JAAS.

Specific details are below:

- **JWKS endpoint:** ``<jimm-url>/.well-known/jwks.json``
- **Key Type/Size:** RSA 4096 bits
- **Signing Algorithm:** RS256
kian99 marked this conversation as resolved.
Show resolved Hide resolved

The following Go packages are used to create the JWKS and JWTs.
kian99 marked this conversation as resolved.
Show resolved Hide resolved

- `<github.com.com/lestrrat-go/jwx/v2/jwa>`__
- `<github.com/lestrrat-go/jwx/v2/jwt>`__
- `<github.com/lestrrat-go/jwx/v2/jwk>`__

User Sessions
-------------

CLI Based Sessions
^^^^^^^^^^^^^^^^^^

When authenticating the Juju CLI to JAAS the user goes through an OAuth login flow (see `Device Code Flow`_).
After login, the CLI is issued a JWT i.e. a session token. This avoids making the user login repeatedly.
kian99 marked this conversation as resolved.
Show resolved Hide resolved

.. hint::
These JWTs use the same technology as the tokens used in communications between JAAS and Juju controllers but
they are not the same tokens.

The session token is eventually stored on the file-system and sent on each request.

Whereas the tokens issued to Juju controllers use asymmetric cryptography, tokens issued to users are signed with
symmetric cryptography. Session tokens are signed using a cryptographic hash function and a shared secret.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Technically we're not signing the tokens with a symmetric algorithm. We just encrypt them.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This has been reworded but what do you mean by this?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The JWT session token we provide to users is signed, and contains the email, which is visible if you put the token into a JWT decoder.

Since there is no need for external parties to verify sessions, only JAAS, who holds the shared secret can verify
the session token.

Note that the JWT contains the user's email and should be secured to avoid a a possible leak of personal information
(in addition to possible malicious use of an account).

Specific details are below:
kian99 marked this conversation as resolved.
Show resolved Hide resolved

- **Key Size:** >=512 bits
- **Signing Algorithm:** HS256
kian99 marked this conversation as resolved.
Show resolved Hide resolved

The following Go packages are used for creating JWTs:

- `<github.com/lestrrat-go/jwx/v2/jwt>`__
- `<github.com/lestrrat-go/jwx/v2/jwa>`__

Browser Cookies
^^^^^^^^^^^^^^^

When using JAAS from the Juju dashboard, a different type of session is created. In this scenario cookies are
used as browsers offer better built in support for cookies.
kian99 marked this conversation as resolved.
Show resolved Hide resolved

After login is completed, the browser is issued with a session cookie. The cookie's stores a cryptographically
kian99 marked this conversation as resolved.
Show resolved Hide resolved
encoded value that allows the server to retrieve the session data.

Specific details are below:

- **Key Size:** >=512 bits
- **Signing Algorithm:** HMAC-SHA256 (the same as HS256 but HS256 is normally used in the context of JWTs)

Note that the browser session cookie does not contain any information beyond an encoded session ID that is
used to lookup the user information. This is in contrast with the CLI session token which contains the user's email.

The following Go libraries are used to handle browser sessions:

- `<github.com/gorilla/sessions>`__
- `<github.com/antonlindstrom/pgstore>`__

OIDC Authentication
-------------------

JAAS employs OAuth 2.0 and OpenID Connect (OIDC) for user authentication,
see `here <https://developer.okta.com/docs/concepts/oauth-openid/>`__
for an overview on these concepts.

Below we outline the various login flows used in JAAS.

The following Go packages are used to implement this functionality:

- `<golang.org/x/oauth2>`__
- `<golang.org/x/oauth2/clientcredentials>`__
- `<github.com/coreos/go-oidc/v3/oidc>`__

Authorisation Code Flow
^^^^^^^^^^^^^^^^^^^^^^^

When performing login via a browser, users go through the authorisation code flow.
This is best described by various diagrams such as
kian99 marked this conversation as resolved.
Show resolved Hide resolved
`this <https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow>`__.

In this flow the user's browser is redirected to the identity provider where they are
asked to login before being redirected back to the original application.

Because JAAS is a server side app, the access token and refresh token are stored
kian99 marked this conversation as resolved.
Show resolved Hide resolved
by the back-end application and a session cookie is issued to the browser as described in
`Browser Cookies`_.

To protect against `CSRF attacks <https://auth0.com/docs/secure/attack-protection/state-parameters>`__
the back-end application issues a random nonce used in the ``state`` parameter of the OAuth
flow. This prevents a malicious attacker from forging a request to login as another user.

Device Code Flow
^^^^^^^^^^^^^^^^

When performing login via the device flow, the Juju CLI will:

1. Request from JAAS a URL and random code which the user can use to login.
2. The CLI will then wait for a response from JAAS.
3. JAAS polls the identity server, which in turn is waiting for the user to complete their login.

A diagram depicting this login flow can be found
`here <https://auth0.com/docs/get-started/authentication-and-authorization-flow/authorization-code-flow>`__.

This process does not rely on browser redirects and so is not susceptible to traditional browser vulnerabilities.
Both the access token and refresh token are obtained and stored by the backend server
and the CLI application is issued with a session token as described in `CLI Based Sessions`_.

Client Credential Flow
^^^^^^^^^^^^^^^^^^^^^^

When there is a need to perform login by a machine rather than a physical user, OAuth handles this through
the use of a client credential flow.

A diagram depicting this login flow can be found
`here <https://auth0.com/docs/get-started/authentication-and-authorization-flow/client-credentials-flow>`__.

This process is reserved for scenarios where machine to machine authentication is required. A good example
of this is includes the use of the Juju Terraform Provider where the client-credential flow is employed.
kian99 marked this conversation as resolved.
Show resolved Hide resolved

In the link above, the client application communicates with the identity provider to retrieve an access token
that is then used with the API server. This design is shifted in JAAS. The client application instead sends
its application credentials to JAAS which then forwards the information to the identity provider. JAAS
effectively acts as a proxy between the client application and the identity provider.

This scheme simplifies authentication for client applications but is only possible since JAAS is a trusted
application in the system.

Macaroons & Offer Authentication
--------------------------------

Macaroons are a tool for decentralised authentication similar to JSON Web Tokens.
The `Go Macaroon package <https://pkg.go.dev/gopkg.in/[email protected]>`__ is used by JAAS and has more
details on the low-level operations that Macaroons are capable of.

Macaroons are used by Juju for various purposes but in JAAS their primary purpose is for authorising
cross-model relations between controllers. When two Juju controllers (that are connected to JAAS)
kian99 marked this conversation as resolved.
Show resolved Hide resolved
communicate for the purposes of sharing an application offer, JAAS acts as the source of truth for
authorisation data. These checks are handled using macaroons.

Macaroons use a combination of HMAC for cryptographic signatures and symmetric encryption to encode
the scope (or caveats) of what a macaroon is entitled to.

These operations are performed using ``HMAC-SHA256`` and ``XSalsa20-Poly1305``. The following Go
packages are used by the underlying macaroon package for these operations:

- ``crypto/hmac``
- ``crypto/sha256``
kian99 marked this conversation as resolved.
Show resolved Hide resolved
- `<golang.org/x/crypto/nacl/secretbox>`__

Additionally, the higher-level `Macaroon Bakery package <https://github.com/go-macaroon-bakery/macaroon-bakery>`__
is used to interface with macaroons and introduces public key cryptography to perform similar operations
as mentioned above. This allows services to trust macaroons generated externally.

These operations are performed using ``Ed25519`` and ``XSalsa20-Poly1305``. The following Go packages are
used by the underlying macaroon bakery package for these operations:

- `<golang.org/x/crypto/nacl/box>`__
- `<golang.org/x/crypto/curve25519>`__

When a Juju controller is connected to JAAS, the ``login-token-refresh-url`` is used to determine where
the JAAS macaroon public key is located. This public key is used when Juju controllers issue macaroons
and enforces that the macaroon can only be discharged by JAAS, who holds the private key. Discharging
kian99 marked this conversation as resolved.
Show resolved Hide resolved
a macaroon refers to the process of verifying its claims.

Specific details are below:

- **Macaroon Public Key endpoint:** ``<jimm-url>/macaroons/publickey``
- **Key Type:** Ed25519 (256-bit key)
- **Signing algorithm:** Ed25519
kian99 marked this conversation as resolved.
Show resolved Hide resolved

TLS Communication
-----------------

In this section we will cover the use of TLS between components of JAAS.

TLS encryption is handled by the Go standard library packages:

- ``crypto/tls``
- ``crypto/x509``

Client - JAAS
^^^^^^^^^^^^^

The Juju client package enforces the use of TLS when connecting to a controller.
This extends to both the Juju CLI and the Juju Terraform Provider.

The minimum supported version is TLS v1.2
kian99 marked this conversation as resolved.
Show resolved Hide resolved

JAAS - Juju Controllers
^^^^^^^^^^^^^^^^^^^^^^^

JAAS enforces the use of TLS when connecting to a Juju controller.

The minimum supported version is TLS v1.2
kian99 marked this conversation as resolved.
Show resolved Hide resolved

JAAS - OpenFGA
^^^^^^^^^^^^^^

JAAS does not currently enforce TLS when communicating with OpenFGA.

TLS is not currently supported with the OpenFGA charm operator.

JAAS - Vault
^^^^^^^^^^^^

JAAS assumes that Vault is reachable with TLS but does not enforce this.
By default the Vault charm employs the use of TLS.

The minimum supported version is TLS v1.2.

JAAS - PostgreSQL
^^^^^^^^^^^^^^^^^

JAAS does not currently enforce TLS when communicating with PostgreSQL.
But this can be achieved when using the PostgreSQL charm.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I would put this differently.
It is possible to achieve TLS by using the PostgresSQL charm and configure it properly by following https://charmhub.io/postgresql-k8s/docs/t-enable-tls


The minimum supported version is TLS v1.2.

CORS
----

CORS or Cross-Origin Resource Sharing is a browser security feature designed to prevent
malicious use of your online credentials. Read more on CORS
`here <https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#what_requests_use_cors>`__.

JAAS supports the use of CORS headers specifically for the purposes of the Juju
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do we want to add that CORS is not supported for WS communications?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes I'll need to mention that.

dashboard. The dashboard requires the ability to send cross-origin requests from the domain
where it is hosted to the domain where JAAS is hosted. More information on how to setup
CORS to securely handle these requests will be available in a future how-to.
kian99 marked this conversation as resolved.
Show resolved Hide resolved

The following Go package is used to validate CORS requests/headers:

- `<github.com/rs/cors>`__

Loading