A simple OIDC‑protected web service for creating and sharing ephemeral, time‑limited secrets via unique links.
Created for SKA's SRCNet. Themed inspired by SKAO colours.
- Authenticated via your organisation’s OIDC issuer
- Per‑secret expiration
- Allowed users and/or groups (from a configurable OIDC claim)
- Encrypted at rest (Fernet)
- SQLite by default (simple single‑pod), Postgres optional
- Docker
- An OIDC client registered at your IdP
Example Redirect URI:
http://localhost:8080/callback
Minimal scopes:openid email
Start from the example, then adapt to your use case.
cp .env.example .envThese are the required environment variables:
# VERSION
IMAGE_TAG=0.3.0
# IMAGE_URL=whispers # in case you build the image locally with `docker build . -t whispers:${IMAGE_TAG}`
# otherwise the IMAGE_URL will default to GHCR.
# OIDC
OIDC_ISSUER=<issuer-url>
OIDC_CLIENT_ID=<client-id>
OIDC_CLIENT_SECRET=<client-secret>
OIDC_REDIRECT_URI=http://localhost:8080/callback
GROUPS_CLAIM=groups
# Encryption
SESSION_SECRET=<random-urlsafe-string>
FERNET_KEY=<base64-urlsafe-fernet-key>
# Base URL
BASE_URL=http://localhost:8080
# Expired secret purge interval
PURGE_INTERVAL_SECONDS=3600# export DOCKER_DEFAULT_PLATFORM=linux/amd64 # might need this on MacOS
docker compose up- Docker, kind, kubectl, Helm
- An OIDC client registered at your IdP
Redirect URI:http://localhost:8080/callback
Scopes:openid email groups
docker build . -t whispers:${IMAGE_TAG}
kind load docker-image whispers:${IMAGE_TAG} -n whispersGenerate a Fernet key:
python -c "from cryptography.fernet import Fernet; print(Fernet.generate_key().decode())"Generate a session secret:
python -c "import secrets; print(secrets.token_urlsafe(32))"Create the Secret:
kubectl create ns whispers
kubectl -n whispers create secret generic whispers-secrets \
--from-literal=OIDC_CLIENT_SECRET='<client-secret>' \
--from-literal=SESSION_SECRET='<session-secret>' \
--from-literal=FERNET_KEY='<fernet-key>'Edit helm/whispers/values.yaml minimally:
env:
OIDC_ISSUER: "https://ska-iam.stfc.ac.uk/"
OIDC_CLIENT_ID: "<client-id>"
OIDC_REDIRECT_URI: "http://localhost:8080/callback"
BASE_URL: "http://localhost:8080"
GROUPS_CLAIM: "groups"
DISABLE_GROUPS: "false"
existingSecret: "whispers-secrets"
sqlite:
enabled: trueInstall:
helm upgrade -i whispers ./helm/whispers -n whispers
kubectl -n whispers port-forward svc/whispers 8080:80Open: http://localhost:8080
- Login with your IAM account.
- Create a secret with title/content, expiration hours, allowed users/groups.
- Share the generated URL (
http://localhost:8080/s/<token>).
If both allowed lists are empty, any authenticated user may view until expiry.
IMAGE_TAG: Image version tag (For docker compose only, use values.yaml for Helm deployment)OIDC_ISSUEROIDC_CLIENT_IDOIDC_CLIENT_SECRETOIDC_REDIRECT_URIOIDC_SCOPES(defaultopenid email groups)GROUPS_CLAIM(defaultgroups)DISABLE_GROUPS(defaultfalse, hide allowed groups field on new whispers)SESSION_SECRET: Any long key should work, used for cookie HMACFERNET_KEY: Used for encryption at-rest. See how to generate one.BASE_URL(no trailing slash)DATABASE_URL(required only if not using SQLite)
Dry-run version calculation:
semantic-release -v --noop versionCreate the release commit and tag locally:
semantic-release version --no-push --no-vcs-release
git push --follow-tags