Skip to content

Commit

Permalink
fix: enumerate tenant and user configs with auth_query
Browse files Browse the repository at this point in the history
  • Loading branch information
chasers committed Nov 3, 2023
1 parent ccc1a2b commit 5db3c24
Show file tree
Hide file tree
Showing 5 changed files with 109 additions and 1 deletion.
File renamed without changes.
41 changes: 41 additions & 0 deletions docs/configuration/tenants.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
All configuration options for a tenant are stored on the `tenant` record in the metadata database used by Supavisor.

A `tenant` is looked via the `external_id` discovered in the incoming client connection.

All `tenant` fields and their types are defined in the `Supavisor.Tenants.Tenant` module.

## Field Descriptions

`db_host` - the hostname of the server to connect to

`db_port` - the port of the server to connect to

`db_database` - the database of the Postgres instance

`external_id` - an id used in an external system used to lookup a tenant

`default_parameter_status` -

`ip_version` - the ip address type of the connection to the database server

`upstream_ssl` -

`upstream_verify` -

`upstream_tls_ca` -

`enforce_ssl` - enforce an SSL connection on client connections

`require_user` - require at least one `user` is created for a tenant

`auth_query` - the query to use when matching credential agains a client connection

`default_pool_size` - the default size of the database pool

`sni_hostname` - the hostname expected on an SSL client connection

`default_max_clients` - the default limit of client connections

`client_idle_timeout` - the maximum duration of an idle client connection

`default_pool_strategy` - the default strategy when pulling available connections from the pool queue
21 changes: 21 additions & 0 deletions docs/configuration/users.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
All configuration options for a tenant `user` are stored on the `user` record in the metadata database used by Supavisor.

All `user` fields and their types are defined in the `Supavisor.Tenants.User` module.

## Field Descriptions

`db_user` - user to match against the client connection user

`db_password` - password to match against the client connection password

`db_user_alias` - client connection user will also match this user record

`is_manager` - these credentials are used to perform management queries against the tenant database

`mode_type` - the pool mode type

`pool_size` - the database connection pool size used to override `default_pool_size` on the `tenant`

`pool_checkout_timeout` - the maximum duration allowed for a client connection to checkout a database connection from the pool

`max_clients` - the maximum amount of client connections allowed for this user
42 changes: 42 additions & 0 deletions docs/connecting/authentication.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
When a client connection is established Supavisor needs to verify the credentials of the connection.

Credential verificiation is done either via `user` records or an `auth_query`.

## Tenant User Record

If no `auth_query` exists on the `tenant` record credentials will be looked up from a `user` and verified against the client connection string credentials.

## Authentication Query

If an `auth_query` exists on the `tenant` this query is used to query the tenant database and return results with credentials.

Create a function to return a username and password for a user:

```sql
CREATE USER supavisor;

REVOKE ALL PRIVILEGES ON SCHEMA public FROM supavisor;

CREATE SCHEMA supavisor AUTHORIZATION supavisor;

CREATE OR REPLACE FUNCTION supavisor.get_auth(p_usename TEXT)
RETURNS TABLE(username TEXT, password TEXT) AS
$$
BEGIN
RAISE WARNING 'Supavisor auth request: %', p_usename;

RETURN QUERY
SELECT usename::TEXT, passwd::TEXT FROM pg_catalog.pg_shadow
WHERE usename = p_usename;
END;
$$ LANGUAGE plpgsql SECURITY DEFINER;

REVOKE ALL ON FUNCTION supavisor.get_auth(p_usename TEXT) FROM PUBLIC;
GRANT EXECUTE ON FUNCTION supavisor.get_auth(p_usename TEXT) TO supavisor;
```

Update the `auth_query` on the `tenant` and it will use this query to match against client connection credentials.

```sql
SELECT * FROM supavisor.get_auth($1)
```
6 changes: 5 additions & 1 deletion mkdocs.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,11 @@ nav:
- Deploy with Fly.io: 'deployment/fly.md'
- Connecting:
- Overview: 'connecting/overview.md'
- Pool Modes: 'connecting/pool_modes.md'
- Authentication: 'connecting/authentication.md'
- Configuration:
- Tenants: 'configuration/tenants.md'
- Users: 'configuration/users.md'
- Pool Modes: 'configuration/pool_modes.md'
- Monitoring:
- Metrics: 'monitoring/metrics.md'
- ORMs:
Expand Down

0 comments on commit 5db3c24

Please sign in to comment.