serverjwtauth

package
v0.0.0-...-94a9b73 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 11, 2022 License: Apache-2.0 Imports: 17 Imported by: 0

README

Temporal JWT Authorization

The Temporal server may be configured to authorize based on JWT sent as a header. The server communicates with an HTTP endpoint that hosts the public keys used to sign tokens (in JWK format, ref RFC 7517). Once the key's signature has been validated, the permissions claim in the token is used to determine what the caller can do. See Temporal security documentation for more details.

This example creates a ECDSA key pair, serves the public key for use by the server, and creates keys as needed for using tctl, running workers, and starting workflows.

Note: Since we are not authorizing the UI in this sample, the server UI will not work with this restricted access. Configuration of SSO for the Temporal Web UI is outside the scope of this example.

Running

Starting the server

First, the public keys must be served for reading by the server. Run the following in a separate terminal to generate a private key and serve its public key:

go run ./serverjwtauth/key gen-and-serve

This will output a line like:

Started JWKS server. Endpoint: http://[::]:61884/jwks.json. Ctrl+C to exit.

This creates a file at key.priv.pem with the private key. The port listed on each run will likely be different, so replace 61884 with the output port in all commands henceforth.

With this running we can start the server. See the primary README about starting the server. docker-compose is suggested for this sample.

Before starting the server you must configure authorization. If using the docker image, the following environment variables should be set:

  • TEMPORAL_JWT_KEY_SOURCE1=http://host.docker.internal:61884/jwks.json
  • TEMPORAL_AUTH_AUTHORIZER=default
  • TEMPORAL_AUTH_CLAIM_MAPPER=default

If using the docker-compose local install, these can be set in docker-compose.yml. If using a standalone server locally, the config is:

global:
  authorization:
    jwtKeyProvider:
      keySourceURIs:
      - http://127.0.0.1:61884/jwks.json
      refreshInterval: 1m
    authorizer: default
    claimMapper: default

With these set, start the server in the background via whatever install method chosen.

Using tctl and registering the default namespace

When starting the server using the docker container, the following excerpt will appear in the logs:

"msg":"uncategorized error","operation":"RegisterNamespace","wf-namespace":"default","error":"Request unauthorized."

This is because by default the docker container attempts to register the default namespace, but cannot because we have restricted access to the server to only authorized uses.

To create this manually, we will use tctl.

We must set the TEMPORAL_CLI_AUTH environment variable with an authorization header value that includes the JWT key. The following command generates a 1 hour key with admin permissions on the system namespace:

go run ./serverjwtauth/key tctl-system-token

This will output something like:

TEMPORAL_CLI_AUTH=Bearer abcde...

See this documentation on how to run tctl with environment variables. If using the docker approach from bash, an argument could be added like:

--env "$(go run ./serverjwtauth/key tctl-system-token)"

Or if using tctl standalone from bash, an export for the environment can be added:

export "$(go run ./serverjwtauth/key tctl-system-token)"

Once tctl is set to take an environment variable, it can be run to create the default namespace:

tctl --ns default namespace register -rd 1
Running the worker and starting the workflow

Now with the server running with authorization enabled and the namespace present, the worker can be run in the background or a separate terminal:

go run ./serverjwtauth/worker

With the worker started, we can run a workflow:

go run ./serverjwtauth/starter

This will output:

Workflow result: Hello Temporal!

Both the worker and starter are configured to dynamically create/rotate JWTs based on the private key. The JWT they use is configured to only have permissions for read/write on the default namespace.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

func GenAndWriteKey

func GenAndWriteKey() error

func ReadKey

func ReadKey() (*ecdsa.PrivateKey, *jose.JSONWebKey, error)

Types

type JWTConfig

type JWTConfig struct {
	Key         *ecdsa.PrivateKey
	KeyID       string
	Permissions []string
	// "exp" is overridden and "sub" is defaulted
	ClaimsTemplate jwt.Claims
	ExtraClaims    interface{}
	// Default is 10m
	Expiration time.Duration
}

func (*JWTConfig) GenToken

func (j *JWTConfig) GenToken() (string, error)

type JWTHeadersProvider

type JWTHeadersProvider struct {
	Config JWTConfig

	// How long before expiration before regen
	RegenLeeway time.Duration
	// contains filtered or unexported fields
}

func (*JWTHeadersProvider) GetHeaders

func (j *JWTHeadersProvider) GetHeaders(ctx context.Context) (map[string]string, error)

Directories

Path Synopsis

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL