Accounts · profiles · credentials

One login. No secret ever handed back out.

One person logs in once. Their profiles hold the credentials for third-party services, and any service that needs one asks keyring for a usable credential at the moment it needs it. No other service stores a secret.

Python 3.12+ Serves on :8001 Encrypted at rest MIT licensed
POST /v1/auth/login                                       -> an opaque session token
POST /v1/profiles                                         -> a named credential set
POST /v1/profiles/{name}/connections/{service}/authorize  -> an OAuth consent URL
GET  /v1/profiles/{name}                                  -> which connections exist, and whether they are live
GET  /v1/internal/credentials/{profile}/{service}         -> headers to attach, for a service acting for a person
No sign-upInvite only. The first account becomes the owner.
Roles are dataAdmin routes are authorised by permission, not by being the operator.
Nobody reads yoursNo role, not even owner, can read another account's credentials.
Verified locallyServices check short-lived tokens against keyring's published keys.

How it works

A person logs in once. Services borrow, and never keep.

Keyring is the authentication root of the LUCY family: every other service verifies its tokens and none of them stores a secret.

01

A person, and their profiles

A login returns an opaque session token. Profiles such as personal and work each hold their own connections: an OAuth grant, an API key, or the fields for a login form.

02

A token for exactly one service

POST /v1/auth/service-token mints a short-lived signed token whose audience is one service's name. That service verifies it locally against the keys keyring publishes.

03

A usable credential, at the moment of use

A service acting for a person presents its own service token and the person's token, and gets back the headers to attach: an OAuth token keyring has already refreshed, never the stored secret.

The API

The HTTP contract, by what it is for.

Interactive docs are at /docs on a running instance. The full contract, with a worked example, is in docs/api.md.

/v1/auth

Sessions and accounts

Log in and out, redeem an invite, change or reset a password, and mint a service token.

/v1/profiles

Profiles and connections

Named credential sets, the consent flow that connects a service, and whether each connection is still live.

/v1/profiles/{name}/grants

Offline grants

Let one service act for you while you are not signed in, for the audiences you name.

/v1/internal

For services

Usable credentials, form secrets and token exchange, each needing the calling service's own token as well as the person's.

/v1/admin

Administration

Roles, invites, account status and the audit log, each route naming the permission it needs.

/.well-known/jwks.json

Published keys

What every other service verifies a token against. GET /healthy and GET /ready need no token.

Run it

Three commands, and no sign-up page.

You need Python 3.12 or newer and uv.

  1. Install.
    make install
  2. Give it a master key and an admin token.
    export KEYRING_MASTER_KEY="$(python -c 'import base64,os; print(base64.b64encode(os.urandom(32)).decode())')" KEYRING_ADMIN_TOKEN="$(python -c 'import secrets; print(secrets.token_urlsafe(32))')"
  3. Serve it; the interactive docs are at /docs.
    make run

There is no sign-up. Mint an invite with the admin token and redeem it with a password; the worked example has both calls. make check is the gate: format, lint, strict types, layering contracts, and the suite at 100% branch coverage.

What it will not do

The lines it holds, and the one you should know about.

Can an administrator read my credentials?

No. Administrators can invite, disable, delete, and see which services somebody has connected and whether each still works. No permission returns another account's credential, and that line is the point of the design.

Can the server itself read them?

Yes, and you should tell the people you onboard. Unattended token refresh needs to decrypt without the owner present, so there is no version of this that refreshes someone's token overnight and cannot read it.

What does it store?

Credentials and nothing else. Browser profiles, cookies, cache and downloaded files belong to the service that uses them.

Can I run it without authentication?

No. It has no unauthenticated mode, and it must sit behind TLS. Read the operations guide before exposing it.

Docs

Written for the person who has to run it.