Skip to content

Commit

Permalink
feat: add jwt docs
Browse files Browse the repository at this point in the history
  • Loading branch information
markphelps committed Jan 9, 2024
1 parent b88c7f4 commit fe970e9
Show file tree
Hide file tree
Showing 7 changed files with 309 additions and 4 deletions.
18 changes: 17 additions & 1 deletion authentication/methods.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -165,6 +165,7 @@ This allows services deployed into the same Kubernetes cluster as Flipt to autom
![Kubernetes Authentication Flow](/images/authentication/kubernetes.svg)

When enabled (see our [Configuration: Method Kubernetes](/configuration/authentication#kubernetes) documentation) a service deployed within Kubernetes can read their service account token from local disk and invoke the verify service account operation on the API.

Given the service account is deemed valid for the surrounding cluster this operation will return a valid Flipt client token with a matching expiration as the service account.
If your Kubernetes environment has short-lived service account tokens, care will be needed to periodically request a new client token using a newly issued service account token.

Expand Down Expand Up @@ -261,5 +262,20 @@ func getClientToken(ctx context.Context) (*Response, error) {

</CodeGroup>

The client token found in the body of the response can be used in the authentication bearer header, as outlined in [Using Client Tokens](/authentication/using-tokens).
The client token found in the body of the response can then be used to authenticate with Flipt as outlined in [Using Client Tokens](/authentication/using-tokens).

The expiration can be used to schedule when to next request a new client token.

## JSON Web Tokens

[JSON Web Tokens](https://jwt.io/) (JWT) are an open, industry standard RFC 7519 method for representing claims securely between two parties. Flipt supports the use of externally created and signed JWTs as a method of authentication.

JWT authentication is useful for scenarios where you want to integrate Flipt with an existing authentication system.

<Note>
JWT authentication is **not** supported by the Flipt UI as it is not a session compatible authentication method.

Check failure on line 276 in authentication/methods.mdx

View workflow job for this annotation

GitHub Actions / lint

Insert `⏎·`
</Note>

![JWT Authentication Flow](/images/authentication/jwt.svg)

The JWT issued by the the Authorization Server can then be used to authenticate with Flipt as outlined in [Using JSON Web Tokens](/authentication/using-jwts).

Check failure on line 281 in authentication/methods.mdx

View workflow job for this annotation

GitHub Actions / lint

Insert `⏎`
8 changes: 8 additions & 0 deletions authentication/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,14 @@ Flipt supports multiple authentication methods for acquiring credentials:

Once a `client token` has been acquired, it can be supplied via request metadata dependent on the protocol. Both HTTP and gRPC examples can be found on the [Using Client Tokens](/authentication/using-tokens) page.

## JSON Web Tokens

Flipt can also authenticate requests using externally created and signed [JSON Web Tokens](https://jwt.io/). This is useful for integrating with existing authentication systems with Flipt.

To enable JWT authentication, you will need to configure Flipt with the public key used to verify the JWT signature.

Check failure on line 57 in authentication/overview.mdx

View workflow job for this annotation

GitHub Actions / lint

Delete `·`

See the [Configuration: JWT Authentication](/configuration/authentication#json-web-token) documentation for details.

## Authorization

Currently, Flipt only supports authentication without any extended authorization capabilities.
Expand Down
88 changes: 88 additions & 0 deletions authentication/using-jwts.mdx
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
---
title: Using JSON Web Tokens
description: This document explains how to handle JSON Web Tokens via both HTTP and gRPC.
---

## HTTP

JSON Web Tokens can only be presented via HTTP requests in the form of an `Authorization` header.

### `Authorization` Header

For applications that communicate with Flipt over HTTP, the `Authorization` header is required.

It must be provided in the form `Authorization: JWT <jwt>`.

The following examples illustrate this in the context of various programming languages:

<CodeGroup>

{/* prettier-ignore */}
```go client.go
import (
"context"
"net/http"
)

func main() {
req := http.NewRequest("GET", "https://flipt.your.instance/api/v1/flags", nil)
req.Header.Set("Authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c")

resp, err := http.Do(req)
// ...
}
```

{/* prettier-ignore */}
```typescript client.ts
import fetch from 'node-fetch';

const headers = { 'Authorization': 'JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c' }
const response = await fetch('https://flipt.your.instance/api/v1/flags', { headers: headers })
```

{/* prettier-ignore */}
```python client.py
import requests

def doRequest():

headers ={"Authorization": "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c"}
requests.get("https://flipt.your.instance/api/v1/flags", headers=headers)

return
```

</CodeGroup>

## GRPC

For gRPC we use the [Metadata](https://grpc.io/docs/what-is-grpc/core-concepts/#metadata) functionality similar to HTTP Headers.
The lower-case `authorization` metadata key should be supplied with a single string `JWT <jwt>` to any RPC calls.

### Example

The following example authenticates a single gRPC client request:

```go rpc.go
func DoRequest(ctx context.Context, flagKey string) {
ctx := metadata.AppendToOutgoingContext(ctx, "authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c")

flag, err := flipt.GetFlags(ctx, &flipt.GetFlagRequest{
Key: flagKey,
})

//...
}
```

This subsequent example demonstrates using a client unary interceptor, which authenticates all outgoing requests:

```go interceptor.go
func AuthUnaryClientInterceptor(optFuncs ...CallOption) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
ctx = metadata.AppendToOutgoingContext(ctx, "authorization", "JWT eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c")
return invoker(ctx, method, req, reply, cc, opts...)
}
}
```
77 changes: 75 additions & 2 deletions configuration/authentication.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -218,7 +218,7 @@ To enable this, you must set the [`use_pkce`](/configuration/overview#authentica
#### Example: OIDC With Google

<Tip>
Checkout our new [Login with Google](/guides/login-with-google) guide for an
Checkout our [Login with Google](/guides/login-with-google) guide for an
in-depth look into configuring Google as an OIDC provider.
</Tip>

Expand Down Expand Up @@ -334,10 +334,83 @@ authentication:
service_account_token_path: /var/run/secrets/kubernetes.io/serviceaccount/token
```

Once enabled, client tokens can be retrieved by sending a Kubernetes pod's service account token to the [VerifyServiceAccount](/reference/authentication/kubernetes-verify-service-account) operation in the API.
Once enabled, client tokens can be retrieved by sending a Kubernetes pod's service account token to the `VerifyServiceAccount` operation in the API.

Further explanation for using this method can be found in the [Authentication: Kubernetes](/authentication/methods#kubernetes) documentation.

### JSON Web Token

The `jwt` method provides the ability to authenticate with Flipt using an externally issued JSON Web Token. This method is useful for integrating with other authentication systems that can issue JWTs (e.g. [Auth0](https://auth0.com/docs/tokens/json-web-tokens)).

Flipt supports asymmetrically signed JWTs using the following algorithm:

- RS256
- RS512
- ES256
- ES512
- EdDSA

This means that the JWT must be signed using an RSA private key and Flipt must be configured with the corresponding public key.

Flipt supports key verification using the following methods:

- [JWKS](https://auth0.com/docs/secure/tokens/json-web-tokens/json-web-key-sets) URL (JSON Web Key Set URL)
- PEM (Privacy Enhanced Mail) encoded public key

<Note>
These methods are mutually exclusive, meaning that only one of them can be configured at a time.

Check failure on line 361 in configuration/authentication.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `These·methods·are·mutually·exclusive,·meaning·that·only·one·of·them·can·be` with `··These·methods·are·mutually·exclusive,·meaning·that·only·one·of·them·can·be⏎·`
</Note>

#### JWKS URL

The `jwks_url` configuration value is a URL that points to a JWKS (JSON Web Key Set) endpoint. This endpoint must return a JSON object that contains a list of public keys that can be used to verify the JWT signature.

```yaml config.yaml
authentication:
methods:
jwt:
enabled: true
jwks_url: https://auth0.com/.well-known/jwks.json
```

#### PEM Encoded Public Key

The `public_key_file` configuration value is the path to a PEM encoded public key that can be used to verify the JWT signature.

```yaml config.yaml
authentication:
methods:
jwt:
enabled: true
public_key_file: /path/to/public_key.pem
```

#### Claim Validation

Flipt supports validating the following claims:

- `iss` (issuer)
- `aud` (audience)
- `exp` (expiration time)
- `nbf` (not before)
- `iat` (issued at)

<Note>

Check failure on line 398 in configuration/authentication.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `⏎··The·`exp`,·`nbf`,·and·`iat`·claims·are·validated·by·default.⏎` with `The·`exp`,·`nbf`,·and·`iat`·claims·are·validated·by·default.`
The `exp`, `nbf`, and `iat` claims are validated by default.
</Note>

To enable claim validation, configure the values in the `validate_claims` configuration option to the expected values.

```yaml config.yaml
authentication:
methods:
jwt:
enabled: true
validate_claims:
issuer: https://auth0.com/
audiences: https://flipt.io/, https://flipt.com/ # at least one audience must match
```

### Common Properties: Cleanup

Each authentication method contains a nested `cleanup` configuration object.
Expand Down
11 changes: 11 additions & 0 deletions configuration/overview.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -184,6 +184,17 @@ export FLIPT_CORS_ALLOWED_ORIGINS="http://localhost:3000 http://localhost:3001"
| authentication.methods.kubernetes.ca_path | Kubernetes API CA certification path | /var/run/secrets/kubernetes.io/serviceaccount/ca.crt | v1.19.0 |
| authentication.methods.kubernetes.service_account_token_path | Path to Flipt service account token | /var/run/secrets/kubernetes.io/serviceaccount/token | v1.19.0 |

#### Authentication Methods: JWT

| Property | Description | Default | Since |

Check failure on line 189 in configuration/overview.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `|·Description·············` with `···|·Description`
| ------------------------------------------------- | ---------------------------------------------------------------- | ------- | ------- |

Check failure on line 190 in configuration/overview.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `----------·|·-------------` with `-------------·|·`
| authentication.methods.jwt.enabled | Enable JWT authentication | false | v1.35.0 |

Check failure on line 191 in configuration/overview.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `|·Enable·JWT·authentication········································` with `····|·Enable·JWT·authentication···························`
| authentication.methods.jwt.jwks_url | URL to retrieve JWKS for JWT validation | | v1.35.0 |

Check failure on line 192 in configuration/overview.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `|·URL·to·retrieve·JWKS·for·JWT·validation··························` with `····|·URL·to·retrieve·JWKS·for·JWT·validation·············`
| authentication.methods.jwt.public_key_file | Path to public key file for JWT validation | | v1.35.0 |

Check failure on line 193 in configuration/overview.mdx

View workflow job for this annotation

GitHub Actions / lint

Replace `|·Path·to·public·key·file·for·JWT·validation······················` with `····|·Path·to·public·key·file·for·JWT·validation··········`
| authentication.methods.jwt.validate_claims.issuer | The issuer claim to validate on JWT tokens | | v1.35.0 |
| authentication.methods.jwt.validate_claims.audiences | The audience claim (list) to validate on JWT tokens | | v1.35.0 |


### Database

| Property | Description | Default | Since |
Expand Down
Loading

0 comments on commit fe970e9

Please sign in to comment.