flowchart LR
Client[Remix App]
Browser
HookClient[Endpoint Clients]
subgraph privateNetwork[Private Network]
Server
Redis[(Redis)]
Postgres[(Postgres)]
SecretsDb[(SecretsDb)]
Worker
Secrets[Secrets Service]
subgraph isolated-docker
Runner
end
end
click Client "https://github.com/zekenie/web-reducer/tree/main/client#readme"
click Server "https://github.com/zekenie/web-reducer/tree/main/server#readme"
click Worker "https://github.com/zekenie/web-reducer/tree/main/server#readme"
click Secrets "https://github.com/zekenie/web-reducer/tree/main/secrets#readme"
click Runner "https://github.com/zekenie/web-reducer/tree/main/runner#readme"
Client <--> Server
Server --> Secrets
HookClient <--> Client
Secrets <--> SecretsDb
Server <--> Redis
Server <--> Postgres
Worker <--> Redis
Worker <--> Postgres
Worker <--> Runner
Browser <--> Client
Redis
classDef selected stroke-width:4px;
class Secrets selected;
The purpose of this service is to hold onto customer secrets. This application is not on the open internet.
Secrets are organized into namespaces. A namespace is essentially a collection of secrets. Secret ⤚ Namespace
. When you create a namespace with the API, you get back an access key you can save. You can perform CRUD operations on secrets in that namespace and retrieve the secrets. This key is hashed in Secret Service and cannot be recreated. It is intended that this key is encrypted when it is stored.
> POST /namespaces HTTP/2
> ...
> Content-Type: application/json
>
< HTTP/2 201 OK
< ...
< Content-Type: application/json
<
{
"accessKey": "Uakgb_J5m9g-0JDMbcJqLJ"
}
> POST /namespaces/Uakgb_J5m9g-0JDMbcJqLJ HTTP/2
> ...
> Content-Type: application/json
>
{
"key": "SECRET_API_KEY",
"value: "foobar"
}
< HTTP/2 201 OK
< ...
< Content-Type: application/json
<
> GET /namespaces/Uakgb_J5m9g-0JDMbcJqLJ HTTP/2
> ...
> Content-Type: application/json
>
< HTTP/2 200 OK
< ...
< Content-Type: application/json
<
{
"SECRET_API_KEY": "foobar"
}
- This service is not on the open internet
- All requests to this service require a secret key auth header (shared)
- Namespace names are non-guessable. In order to find secrets for a hook, you'd need to know the association between
hookId
andnamespaceId
. You'd also need to know the secret key, which is encrypted, so you'd need access to the environment variables of the main server. - Secrets are not stored in plain text, they are encrypted. Each namespace has an encryption key. These keys are themselves encrypted with an environment variable (
KEY_ENCRYPTION_KEY
). This means if the db is leaked, it's useless without the env var.