Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,9 @@ python "$env:HERMES_HOME\plugins\muse-code-subscription\muse_code_login.py"

This mints a stable, account-bound inference key and caches it locally
(`$HERMES_HOME/muse-code-sub.json`, owner-only permissions where supported).
The cache stores exactly `apiKey`, `accountId`, and `email` — the OAuth
access token from the login flow is kept in memory only and never written
to disk.
The key is never printed. Re-run only if access is revoked (401) — the mint
endpoint is aggressively rate-limited, so the plugin never re-mints on its own.

Expand Down
16 changes: 14 additions & 2 deletions muse_code_login.py
Original file line number Diff line number Diff line change
Expand Up @@ -192,11 +192,23 @@ def mint_key(access_token, onboard=True):


def write_cache(credentials, path):
"""Persist credentials with owner-only permissions where supported."""
"""Persist credentials with owner-only permissions where supported.

Retention minimization: only apiKey/accountId/email touch disk. The
OAuth access token has unknown broader scope and nothing reads it back,
so it must never be persisted — sanitize at the sink, whatever the
caller passes in.
"""
cached = {
"apiKey": credentials.get("apiKey"),
"accountId": credentials.get("accountId"),
}
if credentials.get("email"):
cached["email"] = credentials["email"]
directory = os.path.dirname(os.path.abspath(path))
os.makedirs(directory, exist_ok=True)
with open(path, "w", encoding="utf-8") as fh:
json.dump(credentials, fh, indent=2)
json.dump(cached, fh, indent=2)
try:
os.chmod(path, 0o600)
except Exception:
Expand Down
3 changes: 2 additions & 1 deletion plugin.yaml
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
name: muse-code-subscription
kind: model-provider
version: 0.2.0
version: 0.2.1
description: Muse Spark in Hermes billed to the Muse Code monthly login (device-code login, no API key)
author: TheStreamCode
license: MIT
homepage: https://github.com/TheStreamCode/hermes-muse-code
tags: [meta, muse-spark, subscription]
requires_hermes: ">=0.21.3"

6 changes: 4 additions & 2 deletions tests/test_muse_code_provider.py
Original file line number Diff line number Diff line change
Expand Up @@ -241,9 +241,11 @@ def test_full_login_flow_writes_cache(tmp_path):
assert login.main(["--cache", cache]) == 0
assert "ABCD-EFGH" in out.getvalue()
assert "LLM|fresh" not in out.getvalue() # secrets never printed
saved = json.loads(open(cache).read())
raw = open(cache).read()
assert "oauthAccessToken" not in raw # never persisted
assert "dca-new" not in raw
saved = json.loads(raw)
assert saved == {
"oauthAccessToken": "dca-new",
"apiKey": "LLM|fresh",
"accountId": "uid-1",
"email": "user@example.com",
Expand Down
Loading