---
title: Token Signing
---
<BuiltinTable category={"tokensign"}/>
OPA provides two builtins that implement JSON Web Signature [RFC7515](https://datatracker.ietf.org/doc/html/rfc7515) functionality.

`io.jwt.encode_sign_raw()` takes three JSON Objects (strings) as parameters and returns their JWS Compact Serialization.
This builtin should be used by those that want maximum control over the signing and serialization procedure. It is
important to remember that StringOrURI values are compared as case-sensitive strings with no transformations or
canonicalizations applied. Therefore, line breaks and whitespaces are significant.

`io.jwt.encode_sign()` takes three Rego Objects as parameters and returns their JWS Compact Serialization. This builtin
should be used by those that want to use rego objects for signing during policy evaluation.

:::info
Note that with `io.jwt.encode_sign` the Rego objects are serialized to JSON with standard formatting applied
whereas the `io.jwt.encode_sign_raw` built-in will **not** affect whitespace of the strings passed in.
This will mean that the final encoded token may have different string values, but the decoded and parsed
JSON will match.
:::

The following algorithms are supported:

- `ES256`: ECDSA using P-256 and SHA-256
- `ES384`: ECDSA using P-384 and SHA-384
- `ES512`: ECDSA using P-521 and SHA-512
- `HS256`: HMAC using SHA-256
- `HS384`: HMAC using SHA-384
- `HS512`: HMAC using SHA-512
- `PS256`: RSASSA-PSS using SHA256 and MGF1-SHA256
- `PS384`: RSASSA-PSS using SHA384 and MGF1-SHA384
- `PS512`: RSASSA-PSS using SHA512 and MGF1-SHA512
- `RS256`: RSASSA-PKCS-v1.5 using SHA-256
- `RS384`: RSASSA-PKCS-v1.5 using SHA-384
- `RS512`: RSASSA-PKCS-v1.5 using SHA-512

:::info
Note that the key's provided should be base64 URL encoded (without padding) as per the specification ([RFC7517](https://datatracker.ietf.org/doc/html/rfc7517)).
This differs from the plain text secrets provided with the algorithm specific verify built-ins described below.
:::

## Examples

### `encode_sign`

<PlaygroundExample dir={require.context("../_examples/io.jwt/encode_sign/sign")} />

<PlaygroundExample dir={require.context("../_examples/io.jwt/encode_sign/hmac")} />

<PlaygroundExample dir={require.context("../_examples/io.jwt/encode_sign/empty_json")} />

<PlaygroundExample dir={require.context("../_examples/io.jwt/encode_sign/rsa")} />

### `encode_sign_raw`

<PlaygroundExample dir={require.context("../_examples/io.jwt/encode_sign_raw/sign_raw")} />
