No description
  • Go 97.5%
  • Shell 1.4%
  • PowerShell 1.1%
Find a file
Repository files (latest commit first)
Filename Latest commit message Latest commit date
2026-08-01 19:43:32 -05:00
.github Correct v1.1.1 package list 2026-08-01 19:43:32 -05:00
cmd Support project API keys and compact layout 2026-08-01 19:08:36 -05:00
internal Support project API keys and compact layout 2026-08-01 19:08:36 -05:00
scripts Make Windows release builds repeatable 2026-07-29 10:43:22 -05:00
.gitignore Release UsageBoard 1.0.1 2026-07-29 10:17:58 -05:00
go.mod Initial UsageBoard 1.0.0 release 2026-07-29 08:39:51 -05:00
go.sum Initial UsageBoard 1.0.0 release 2026-07-29 08:39:51 -05:00
README.md Support project API keys and compact layout 2026-08-01 19:08:36 -05:00
SECURITY.md Support project API keys and compact layout 2026-08-01 19:08:36 -05:00

AI Usage Board

AI Usage Board is a Go/Fyne desktop dashboard for monitoring AI subscription quota windows and organization API spend. It supports multiple OpenAI Codex subscription connections, one experimental Claude subscription connection, and separate OpenAI API-key and Claude API-billing connections.

What it does

  • Opens OpenAI authentication in the system browser using Authorization Code, PKCE, OIDC nonce validation, and a loopback callback on port 1455.
  • Keeps status, retry, copy-link, cancellation, timeout, and errors in a separate setup window that closes automatically after a successful encrypted save.
  • Connects one experimental Claude account by importing the stored Claude Code subscription login read-only; it never runs Claude Code or reads browser cookies.
  • Adds OpenAI API connections with either a normal project key or an organization Admin key, while Claude API billing remains Admin-key only. Dedicated setup windows use masked entry and immediate validation.
  • Shows one responsive card per connection with plan, short and weekly quota windows, percentage remaining, local reset countdowns, connection state, last successful update, credit balance when supplied, and provider-reported month-to-date organization API spend for Admin-backed billing connections. Unsupported spend, credit, and quota fields are hidden rather than shown as zero or unavailable.
  • Starts with a compact 540x1000 canvas and a responsive two-column control grid while preserving larger saved window preferences.
  • Supports connect, reconnect, rename, reorder, remove, per-card refresh, and refresh all without rebuilding or unexpectedly resizing the main window.
  • Polls each account at the top of every minute with serialized requests, offline and wake recovery, Retry-After handling, bounded jittered backoff, and stale-snapshot preservation. Losing desktop focus alone does not pause polling.
  • Prevents concurrent app instances from racing the encrypted vault.

The Windows release is a GUI executable and does not open a terminal window. The optional Always on top toggle is currently available on Windows.

Build and test

The checked-in release toolchain is Go 1.26.4. Fyne 2.8 requires a C compiler and platform graphics development libraries.

go mod download
go test ./...
go vet ./...

Build a Windows release with its application icon and GUI subsystem:

.\scripts\build-windows.ps1

The resulting executable is:

dist\UsageBoard-windows-amd64.exe

macOS and Linux packaging is available through scripts/build-unix.sh. Release packaging is native-only: the requested operating system and architecture must match the build host. The Linux path accepts Fyne's .tar.gz output or converts its current .tar.xz output, then rebuilds the published .tar.gz artifact with root ownership, safe 0755/0644 modes, sorted paths, and reproducible archive timestamps.

Forgejo Actions tests and packages Windows x64, macOS Apple Silicon, and Linux x86_64 from an annotated release tag. Completed packages and their aggregate SHA256SUMS manifest are available from the corresponding Forgejo release.

Release checksums protect download integrity, but the current artifacts are not publisher-signed. The Windows executable is not Authenticode signed. The macOS application is not Developer ID signed or notarized. Windows SmartScreen or macOS Gatekeeper may therefore warn about or block a downloaded package.

Credential storage

The versioned age-encrypted vault is stored under the user's configuration directory:

usageboard/credentials.age

Only one process can own this vault at a time. The default X25519 age identity is protected as UsageBoard / age-identity by Windows Credential Manager, macOS Keychain, or Linux Secret Service.

If no platform credential service is available, the app requires an age scrypt passphrase. New passphrase vaults require at least 12 characters. For controlled development environments only, USAGEBOARD_PASSPHRASE can provide the passphrase at process startup; the variable is cleared immediately and should never be stored in shell history or a checked-in file.

There is no plaintext credential fallback. If the protected age identity or passphrase is lost, the encrypted vault can be preserved as a recovery file before reconnecting accounts.

OpenAI provider notes

The adapter follows the Codex/OpenClaw-compatible browser flow and polls:

GET https://chatgpt.com/backend-api/wham/usage
Authorization: Bearer <access token>
ChatGPT-Account-Id: <account id>

Usage is an HTTPS polling interface, not a WebSocket feed. The endpoint is version-sensitive and is not a versioned public API, so URLs, scopes, headers, and response parsing remain isolated inside the OpenAI adapter.

Every response is bounded and validated. Missing or mismatched account identifiers, invalid quota windows, malformed balances, unexpected redirects, and invalid identity tokens fail closed while the previous successful snapshot remains visible as stale.

API key and billing connections

Use Add OpenAI API or Add Claude API above the connection cards. These buttons open a separate setup window with a masked key field. The field is cleared immediately when validation starts; a validated key is saved only in the age-encrypted vault. Closing or cancelling the window stops validation and leaves no partial credential. Use Update key on an API card to rotate a key for the same project or organization and access profile.

OpenAI supports two credential profiles:

  • A normal OpenAI project API key is validated read-only with GET https://api.openai.com/v1/models. Listing accessible model metadata does not create a model-inference request. The card shows connection details and the last successful update, but no spend, credit, or quota fields because those values are unavailable to the project key.
  • An OpenAI organization Admin API key is validated against the official GET https://api.openai.com/v1/organization/costs endpoint and can show provider-reported organization-wide month-to-date spend. See OpenAI's Admin API key reference.
  • Claude API Billing requires a Claude Platform organization Admin API key (sk-ant-admin01-...), not a normal inference key. Individual Claude accounts are unsupported. See Anthropic's Admin API key guide. UsageBoard validates the organization with GET https://api.anthropic.com/v1/organizations/me and reads GET https://api.anthropic.com/v1/organizations/cost_report.

Admin-backed cards label the value Month-to-date API spend • Organization-wide; project-key cards omit the entire spend row. The Claude card also visibly states that Priority Tier is excluded. An entered Admin key is a reporting credential and is not necessarily the inference key that incurred the cost. Anthropic does not expose authoritative dollar cost grouped by inference API-key ID, so UsageBoard does not present an estimated per-key dollar value as exact. Claude Priority Tier costs are not included in Anthropic's cost report. Billing data may lag provider activity. Neither documented reporting API supplies a remaining prepaid-credit balance.

Project-key validation and API billing are polled at the same top-of-minute cadence as subscription quota. Static API keys are never sent through OAuth refresh logic. Redirects are blocked, response sizes and page counts are bounded, pagination cursors are validated, and monetary values are summed with exact decimal arithmetic. When OpenAI does not expose a stable project or organization identity, UsageBoard keeps an opaque local connection binding only when you explicitly choose Update key and the replacement passes the appropriate validation. The setup window warns that this fallback cannot independently prove the replacement belongs to the same project or organization; verified, differing identities or access profiles are rejected.

Claude provider status

Claude support is experimental and intentionally limited to one connection.

Warning

Anthropic's current authentication guidance says Claude Code OAuth is designed for Claude Code and other native Anthropic applications and directs third-party products to API keys. This quota-only adapter does not route inference, but use of the undocumented subscription endpoint is not explicitly authorized. Confirm applicability or permission before distributing or enabling it.

The Connect Claude setup window imports the stored Claude Code subscription login from this computer read-only; it does not open a Claude browser-login flow. UsageBoard does not run the Claude CLI, parse CLI output, read browser cookies, or retain, use, rotate, or write Claude Code's refresh token. It retains only the short-lived access token and safe account metadata in the age-encrypted vault, and clears raw credential-document buffers immediately after parsing.

UsageBoard refuses the import when it detects a higher-priority Claude Code authentication source, including cloud-backend flags, environment credentials, or a user-level apiKeyHelper. It never reads or displays those credential values.

Credential sources are platform-specific:

  • Windows: %CLAUDE_CONFIG_DIR%\.credentials.json, or %USERPROFILE%\.claude\.credentials.json when the override is unset.
  • Linux: $CLAUDE_CONFIG_DIR/.credentials.json, or ~/.claude/.credentials.json when the override is unset. The file must not be accessible to group or other users.
  • macOS: the Claude Code-credentials generic-password item in Keychain only; there is no credentials-file fallback. Keychain is read only after an explicit Connect or Reconnect action. Automatic background refresh never reads Keychain and therefore cannot trigger an access prompt; reconnect manually after the imported access token expires.

On Windows and Linux, token refresh means re-reading the same read-only Claude Code credential file and rejecting an account-identity change. On macOS, background re-read is disabled as described above. In all cases, UsageBoard never uses the Claude refresh token.

Claude quota is polled at the top of every minute from:

GET https://api.anthropic.com/api/oauth/usage
Authorization: Bearer <imported access token>

This subscription-usage endpoint is undocumented and version-sensitive. It may change or stop accepting Claude Code subscription credentials without notice. Failures preserve the last successful snapshot as stale; there is no website scraping or browser-cookie fallback.

Security

See SECURITY.md for the local vault, OAuth, and reporting boundaries.