SLKVS

A Redis-backed key-value store for the reckless and the careful alike.

SLKVS stores values under compound keys of the form kvs_{realm}__{key}. Every operation requires a realm and a key. Optional secure marking protects keys from unauthorised writes.

GET /api?method=get&realm=…&key=…

Retrieves the value for a given realm and key. Returns the raw value on success, or a 404 JSON error if the key does not exist.

Request
curl https://host/api?method=get&realm=production&key=db_url
Response — 200 OK
postgres://user:pass@primary:5432/slkvs
Response — 404 Not Found
{ "error": "Key not found" }
POST /api

Stores a value. If the key has been marked secure, a matching secret must be provided; otherwise the request is rejected with 403.

Request
curl https://host/api \
-X POST \
-H "Content-Type: application/json" \
-d '{ "method": "set", "realm": "staging", "key": "api_key", "value": "sk-abc123" }'
Response
{ "success": true }
POST /api

Deletes a key and its associated security metadata. Like set, this requires the secret if the key is marked secure.

Request
curl https://host/api \
-X POST \
-H "Content-Type: application/json" \
-d '{ "method": "remove", "realm": "staging", "key": "api_key" }'
Response
{ "success": true }
POST /api

Marks a key or list as secure. Once marked, every set / remove (or listset / listremove) call must include the correct secret. The secret is hashed with bcrypt before storage — SLKVS never stores plaintext secrets. Getting a value or listing members never requires a secret.

Request — secure a scalar key
curl https://host/api \
-X POST \
-H "Content-Type: application/json" \
-d '{ "method": "setsecure", "realm": "production", "key": "db_url", "secret": "hunter2" }'
Request — secure a list
curl https://host/api \
-X POST \
-H "Content-Type: application/json" \
-d '{ "method": "setsecure", "list": "club1|OWNER_UUID", "secret": "hunter2" }'
Response
{ "success": true }
POST /api

Adds or updates a member in a named list. The list parameter identifies the group, key is the member identifier (OBJECT_UUID), and value is its URL. If the list has been secured with setsecure, a matching secret is required. Lists are stored as Redis hashes — created on first use, no setup required.

Request
curl https://host/api \
-X POST \
-H "Content-Type: application/json" \
-d '{ "method": "listset", "list": "club1|OWNER_UUID", "key": "OBJECT_UUID", "value": "https://example.com/webhook" }'
Response
{ "success": true, "member": "OBJECT_UUID" }
POST /api

Removes a member from a list. Idempotent — succeeds even if the member does not exist. If the list is secured, the secret must be provided.

Request
curl https://host/api \
-X POST \
-H "Content-Type: application/json" \
-d '{ "method": "listremove", "list": "club1|OWNER_UUID", "key": "OBJECT_UUID" }'
Response
{ "success": true, "member": "OBJECT_UUID" }
GET /api?method=listget&list=…

Returns all members of a list as a JSON object mapping OBJECT_UUID to URL. Returns {} for an empty or non-existent list.

Request
curl https://host/api?method=listget&list=club1|OWNER_UUID
Response
{ "OBJECT_UUID": "https://example.com/webhook" }

Parameters

NameRequiredDescription
methodalwaysOne of get, set, remove, setsecure, listset, listremove, listget
realmsinglesNamespace / partition for scalar keys
keysingles / listset & listremoveScalar key name, or member identifier inside a list
listlistsList name (e.g. scope|owner_uuid)
valueset / listsetValue to store (string / URL)
secretsetsecure / secure opsSecret for marking or accessing a secure key or list

Notes