End to End Identity

The CipherStash Proxy can propagate individual customer identity and context with data access logs for visibility.

Overview

Identity and Context are passed using custom SET commands that behave similarly to other PostgreSQL SET commands.

Identity enables a JWT to be passed to the proxy, verified and the sub (subject) and aud (audience) values to be extracted (if present) and passed with audit logs. See RFC: 7519 JSON Web Token for further details.

Context accepts arbitrary JSON data to be associated with the data access logs. The context data can be used to refine search and analysis in the dashboard.

Available commands:

  • SET IDENTITY { TO | = } 'jwt_token'
  • SET CONTEXT { TO | = } 'json'
  • RESET {IDENTITY | CONTEXT}

Both Identity and Context data are tied to the current connection or transaction context. The application is responsible for ensuring that data is reset.

Set Identity

Set a JWT token that will be verified and decoded.

Syntax

1SET IDENTITY { TO | = } 'jwt_token'
2

Description

The SET IDENTITY command changes the run-time identity.

The input parameter is expected to be a valid JWT token.

The token is validated against authorised issuers and audiences configured in the CipherStash Workspace.

If issuer and audience are valid, the JWT token is decoded and the issuer, audience and subscriber values are extracted and propagated with the Statement Audit Log.

1                              Validate &
2                              Decode JWT
3                              ┌─────┐
4                              │     │
5                              │     │
6                              │     │
7 ┌─────────┐                ┌─┴─────▼─┐            ┌─────────┐
8 │         │                │         │            │         │
9App   ├────────────────┤  Proxy  ├────────────┤   DB10 │         │  SET IDENTITY  │         │            │         │
11 └─────────┘                └────┬────┘            └─────────┘
1213                                 │ Audit
14Log
151617

Issuers and Audience

In order to validate and decode JWT tokens, the approved Issuers and Audiences (if appropriate) need to be added to your CipherStash Workspace configuration.

{INSERT DETAILS ON ISSUERS}

Example

1
2## Set JWT Token
3SET IDENTITY = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJzdWJzY3JpYmVyIiwic3ViIjoiMTIzNDU2Nzg5MCIsInVzZXJuYW1lIjoiVXNlcjQyIiwiaWF0IjoxNTE2MjM5MDIyfQ.o1SrsJO_CLwdcPGHrgacQrP8wwIQr-CgoO99-pOVfvQ'
4
5## Decoded Data
6{
7  "aud": "",
8  "sub": "1234567890",
9  "username": "User42",
10  "iat": 1516239022
11}
12
13## Propagated Data
14
15{
16  "aud": "",
17  "sub": "1234567890"
18}
19

Reset Identity

Immediately clear identity information.

Syntax

1RESET IDENTITY
2

Description

The RESET IDENTITY command clears the run-time identity data.

Set Context

Sets arbitrary JSON data to be with statement Audit log.

Syntax

1SET CONTEXT { TO | = } 'json'
2

Description

The SET CONTEXT command changes the run-time context that is propagated with the Statement Audit Log.

The input parameter is expected to be a valid JSON string. The parameter will be checked to ensure it can be parsed as JSON, but no other restrictions or requirements apply.

If the input parameter is invalid, an error will be logged. Invalid JSON values are still propagated.

Reset Context

Immediately clear context information.

Syntax

1RESET CONTEXT
2

Description

The RESET CONTEXT command clears the run-time context.


Rails Example

In Rails, an around_action can SET and RESET the context or identity for all statements run inside the controller. Context data can be loaded or extracted from the session.

1class BaseController < ApplicationController
2  around_action :wrap_in_context
3
4  private
5    def wrap_in_context
6      begin
7        ActiveRecord::Base.connection.execute("SET CONTEXT '{...}'")
8        yield
9      ensure
10        ActiveRecord::Base.connection.execute("RESET CONTEXT")
11      end
12    end
13end
14
15

Lifecycle

Transaction Mode

In transaction mode, a client is connected for the duration of a transaction. The connection is returned to the pool once the transaction is complete.

This mode is enabled by default.

An application can start a transaction and execute multiple statements against the same underlying connection to the database.

As transactions complete, and connections returned to the pool, any set identity or context information is discarded.

Data can be changed at any time by executing SET {IDENTITY | CONTEXT} or RESET {IDENTITY | CONTEXT}.

Session Mode

Session mode is the normal behaviour of Postgres connections in the wild. In Session mode, the connection context lives until the client closes the connection.

The identity is retained until the next SET {IDENTITY | CONTEXT} statement or RESET {IDENTITY | CONTEXT} is called.

Example Session Mode Flow

In this example, the App has called SET IDENTITY before executing multiple statements.

Both statements will be executed by the proxy with the same identity.

1App   -> Connect
2
3Proxy -> Database Connection
4
5App   -> SET IDENTITY
6
7App   -> Statement
8
9Proxy -> Executes Statement [with IDENTITY]
10
11App   -> Statement
12
13Proxy -> Executes Statement [with IDENTITY]
14
15App   -> Close Connection
16