Rename Installation to Instance
Follows the portal: the noun is "instance" everywhere the app says it — UI strings, CLI output, error details, docs and comments. The wire keys (`instance_id`, `instance_token`) and the hub route this calls move with it. An existing cloud.json is adopted rather than refused: without the key alias the dataclass fails to parse, which the caller swallows and reads as "never enrolled" instead of "reconnect". `instance_key` on a node type becomes `target_key`. It means the outside thing a node points at, which is a different sense of the word, and keeping both would put two meanings of "instance" in one codebase. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015YrQnKV3bnQd4K342y8tKj
This commit is contained in:
@@ -1,4 +1,4 @@
|
||||
"""What this installation knows about the portal it is enrolled with.
|
||||
"""What this instance knows about the portal it is enrolled with.
|
||||
|
||||
One file on the data volume, beside the OAuth keypair and for the same reason:
|
||||
it is a credential, it must survive a rebuild, and it must never be in the
|
||||
@@ -9,7 +9,7 @@ portal still believes.
|
||||
The portal's public keys are stored here rather than fetched: they are pinned
|
||||
at enrolment, when a person was holding a claim code they had just read off the
|
||||
portal's own screen. A hub whose DNS or TLS is later hijacked cannot re-key an
|
||||
installation that already enrolled; it can only fail to verify.
|
||||
instance that already enrolled; it can only fail to verify.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
@@ -42,11 +42,11 @@ VIA_PORTAL = secrets.token_urlsafe(16)
|
||||
class CloudConfig:
|
||||
portal_url: str
|
||||
ws_url: str
|
||||
installation_id: str
|
||||
instance_id: str
|
||||
token: str
|
||||
issuer: str
|
||||
jwks: dict[str, Any]
|
||||
#: The local account this installation acts as on its own behalf: what the
|
||||
#: The local account this instance acts as on its own behalf: what the
|
||||
#: health summary is collected as, and what a screen paired through the
|
||||
#: portal borrows for want of a person. Recorded at enrolment from whoever
|
||||
#: performed it. Portal *sessions* no longer come through here — they name
|
||||
@@ -72,6 +72,10 @@ def _read() -> CloudConfig | None:
|
||||
return _cache[1]
|
||||
try:
|
||||
data = json.loads(path.read_text())
|
||||
# A file written before the installation/instance rename. Adopt it
|
||||
# rather than failing to parse, which would read as "never enrolled".
|
||||
if "installation_id" in data:
|
||||
data["instance_id"] = data.pop("installation_id")
|
||||
config = CloudConfig(**data)
|
||||
except (OSError, ValueError, TypeError):
|
||||
logger.exception("Could not read %s; remote access stays off", path)
|
||||
@@ -109,15 +113,15 @@ def delete() -> None:
|
||||
|
||||
|
||||
def decode_portal_token(token: str) -> dict[str, Any]:
|
||||
"""Validate a token the portal minted for this installation.
|
||||
"""Validate a token the portal minted for this instance.
|
||||
|
||||
Raises ``InvalidTokenError`` for everything else, including the ordinary
|
||||
case of not being enrolled at all — which is what makes this branch free
|
||||
for an installation nobody connected.
|
||||
for an instance nobody connected.
|
||||
"""
|
||||
config = _read()
|
||||
if config is None:
|
||||
raise InvalidTokenError("this installation is not enrolled with a portal")
|
||||
raise InvalidTokenError("this instance is not enrolled with a portal")
|
||||
|
||||
try:
|
||||
key = jwt.PyJWKSet.from_dict(config.jwks).keys[0]
|
||||
@@ -128,9 +132,9 @@ def decode_portal_token(token: str) -> dict[str, Any]:
|
||||
token,
|
||||
key,
|
||||
algorithms=["RS256"],
|
||||
# The audience is this installation's own id, so a token the portal
|
||||
# The audience is this instance's own id, so a token the portal
|
||||
# minted for somebody else's machine fails here.
|
||||
audience=config.installation_id,
|
||||
audience=config.instance_id,
|
||||
issuer=config.issuer,
|
||||
)
|
||||
scope = claims.get("scope")
|
||||
|
||||
Reference in New Issue
Block a user