Add per-user daily token quota with persistent usage tracking

This commit is contained in:
2026-08-21 12:25:57 -07:00
parent 2c3dc66878
commit f1200b7d79
6 changed files with 199 additions and 45 deletions

View File

@@ -128,32 +128,41 @@ The `.gitignore` file excludes `node_modules` and common system files from commi
## Deploy for the whole company
Use this when the tool needs to be reachable by anyone on the internal network or VPN, not just on one person's machine. This uses a company-owned Anthropic API key shared by everyone who reaches the tool, so it adds a login gate and a request cap that a solo local setup does not need.
Use this when the tool needs to be reachable by anyone on the internal network or VPN, not just on one person's machine. This uses a company-owned Anthropic API key shared by everyone who reaches the tool, so it adds a per-person login, a per-person daily token quota, and a request cap that a solo local setup does not need.
1. Get an Anthropic API key billed to a company account, not a personal one. IT or finance should provision this, since it is billed like any other company vendor cost.
2. Pick a shared username and password for this tool. This is a simple login gate, not a full identity system. It exists so the tool is not reachable by anyone who is merely on the same network segment, but treat the VPN and internal network as the primary control, not this login.
2. Decide who needs their own login. Each name gets its own password and its own daily token quota, tracked separately.
3. On the host or container platform, set these values as environment variables, or in a `.env` file next to `docker-compose.yml`:
```
ANTHROPIC_API_KEY=<company key>
APP_USERNAME=<shared username>
APP_PASSWORD=<shared password>
APP_USERS=alice:pass1,bob:pass2,carol:pass3
TOKEN_LIMIT_PER_USER=50000
```
4. Build and run the container:
```
docker compose up -d --build
```
5. To run this alongside the existing Work Package Suite container instead of on its own, copy the `sde-meeting-toolkit` service block from `docker-compose.yml` into that stack's compose file, and apply the same environment variables there.
6. Confirm the login prompt appears when you open the tool's URL from another machine on the network.
5. To run this alongside the existing Work Package Suite container instead of on its own, copy the `sde-meeting-toolkit` service block from `docker-compose.yml` into that stack's compose file, including its `volumes` entry, and apply the same environment variables there.
6. Confirm the login prompt appears when you open the tool's URL from another machine on the network, and that it accepts one of the named user/password pairs.
### What the login gate does and does not do
- It requires a username and password before any page or API call on this tool succeeds.
- It requires a username and password before any page or API call on this tool succeeds, and identifies which named user made each AI draft call.
- It does not encrypt traffic on its own. Run this behind the same network and VPN protections used for the Work Package Suite, and add TLS at the reverse proxy or load balancer if one is already in place for that stack.
- It does not track who made which AI draft request. Every user shares one login and one API key. If per-person attribution matters later, that needs a real identity integration, which is a larger change than this tool currently supports.
- It is a shared-credential list, not a real identity system. Anyone who has a name's password can use that name's quota. If real single-sign-on attribution matters later, that needs a larger integration than this tool currently supports.
- Old single-shared-login setups still work: set `APP_USERNAME` and `APP_PASSWORD` instead of `APP_USERS` if you want everyone to share one login and one quota, unchanged from before this feature existed.
### Per-user token quota
`TOKEN_LIMIT_PER_USER` caps combined input and output tokens per named user, per UTC calendar day. Default: 50000 tokens/day, which is roughly 100 to 200 AI drafts with this tool's prompt size. A user who hits the cap gets a clear error naming their usage and the time until reset, instead of a silent failure or an unexplained cost.
Usage is written to `TOKEN_USAGE_FILE` (default `./data/token-usage.json`) after every AI call. In Docker, `docker-compose.yml` mounts `./data` as a volume so this file survives a restart or redeploy. If you remove that volume mount, usage resets to zero every time the container restarts, which defeats the point of a daily cap.
To reset one person's quota early, stop the container, edit their entry out of the usage file (or set its `date` to any past date), and restart. To raise or lower the cap for everyone, change `TOKEN_LIMIT_PER_USER` and restart; the change applies from that point on, not retroactively.
### Rate limit
`RATE_LIMIT_MAX` and `RATE_LIMIT_WINDOW_MS` cap AI draft requests per source IP address, to prevent a leaked link or a stuck script from running up cost on the shared key. Defaults: 20 requests per 5 minutes. Raise these in `.env` if real usage hits the limit; the tool returns a clear rate-limit error rather than failing silently.
`RATE_LIMIT_MAX` and `RATE_LIMIT_WINDOW_MS` cap AI draft requests per source IP address, independent of the token quota. This catches a runaway script in the first few seconds, before it could burn through a whole day's token quota. Defaults: 20 requests per 5 minutes.
## Relation to the Work Package Suite