Public Access
Spelunk: sign each device in through the browser instead of keeping Spelunk API keys in the vault
A Spelunk API key reaches one organisation, so a server elsewhere - oc-linux in Orange Climate - was refused before it reached the agent. Each device now signs in to a Spelunk once, under Settings -> Security -> Spelunk or from a Spelunk host's editor: the OAuth authorization code flow with PKCE for a native app (RFC 8252), with Spelunk as the authorization server. The browser opens Spelunk's /api/app-sign-in/authorize with a loopback redirect (the app's own scheme on Android), the person signs in there however they normally do and allows "DodoSSH on <device>", and the code is redeemed at /api/app-sign-in/token for an app session token. That token opens terminals in every organisation its person is in, with the role they have on each server at the time; tunnel tickets send no organisation. The sign-in stays on the device: sealed in the local cache under the LocalCacheKey (AAD resource type 18, bound to its row), never synced, wiped with the cache, and only ever sent to the Spelunk it came from. A 401 from Spelunk forgets it; SIGN OUT ends it there and here, and so does signing out of DodoSSH. Before every Spelunk connection DodoSSH asks its own identity provider whether its sign-in still stands (a forced refresh, at most once a minute), and an account it refuses is signed out of DodoSSH and of every Spelunk on the device. A route names no key any more: Spelunk hosts are written at host schema 11, which an older build shows read-only and asks to be updated for, and a payload that still names a key credential decodes with the id skipped. The SpelunkKey item type is gone: SyncEntityType 14, ChangeEntityType 14 and AAD type 17 are retired, the server drops spelunk_key and its change-log rows, and the client cache drops its cached items, outbox entries and conflicts of that type. A link still never starts a sign-in: from a Spelunk this device is not signed in to it opens the editor, which offers to. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
1 parent
902761d37b
commit
ef365f462e
62 files changed
+4327
-1945
No files matched your search
@@ -456,30 +456,40 @@ phone runs forwards too, listed behind a `⇄` in its terminal's bar, but cannot
|
||||
|
||||
A server managed by Spelunk runs Spelunk's agent, which keeps a connection open to Spelunk. DodoSSH can use
|
||||
that connection instead of dialling: tick **Connect through Spelunk** in the host editor and fill in
|
||||
Spelunk's API address, the server's id in Spelunk, and your Spelunk API key. A connection then asks Spelunk
|
||||
for a ticket, opens a WebSocket, and the agent connects to the SSH server on the machine's own loopback — so
|
||||
the server needs no open SSH port at all. Shells and file transfers both go this way; the relay and Spelunk
|
||||
are one choice, and ticking one unticks the other.
|
||||
Spelunk's API address and the server's id in Spelunk. A connection then asks Spelunk for a ticket, opens a
|
||||
WebSocket, and the agent connects to the SSH server on the machine's own loopback — so the server needs no
|
||||
open SSH port at all. Shells and file transfers both go this way; the relay and Spelunk are one choice, and
|
||||
ticking one unticks the other.
|
||||
|
||||
- **Fill in the API key once, under Settings → Security → Spelunk.** Give Spelunk's API address and paste
|
||||
the key (`spelunk_…`, with the Admin role). It is saved as a *Spelunk key* in your personal vault —
|
||||
encrypted, synced to your other devices, never shown again — together with the address, and **it is only
|
||||
ever sent to that address**: a host that names the key with any other address is refused at connect. One
|
||||
key serves every server in that Spelunk organisation; saving a key for an address that already has one
|
||||
replaces it, and every host using it connects with the new key. The host editor offers saved keys first
|
||||
and picks the one for the address you type. The API address must be `https://`, except for a Spelunk on
|
||||
this machine.
|
||||
- A key kept the older way, as a credential's password, still works and is still offered in the editor;
|
||||
its password goes to whatever address the host names.
|
||||
- **Sign this device in to Spelunk once, under Settings → Security → Spelunk** (or with the button in a
|
||||
Spelunk host's editor). Give Spelunk's API address and press SIGN IN: your browser opens at Spelunk, you
|
||||
sign in there however you normally do — password, passkey, your company's single sign-on, second factor —
|
||||
and allow *DodoSSH on "<this device>"*. No key is pasted anywhere, and DodoSSH never sees your Spelunk
|
||||
password.
|
||||
- **One sign-in reaches every organisation you are in** on that Spelunk, as you, with the role you have on
|
||||
each server at the time: Admin opens a terminal, anything less is refused for that server alone. DodoSSH
|
||||
sends no organisation; Spelunk takes it from the server.
|
||||
- **It stays on this device.** Nothing about it is synced: each device signs in on its own, and the host
|
||||
itself carries only the address and the server id, so the same host opens on every device signed in to its
|
||||
Spelunk. The sign-in is sealed in the local cache like the remembered DodoSSH sign-in, and only ever sent to
|
||||
the Spelunk it came from. The API address must be `https://`, except for a Spelunk on this machine.
|
||||
- **It has no expiry, and ends with you.** Spelunk refuses it once you are removed, change your password or
|
||||
second factors, or sign it out under *Your account → Signed-in apps* there; DodoSSH then forgets it and asks
|
||||
you to sign in again. SIGN OUT beside it under Settings → Security ends it in both places, and so does
|
||||
signing out of DodoSSH.
|
||||
- **DodoSSH has to be online and signed in.** Before every connection through Spelunk it asks its identity
|
||||
provider whether your DodoSSH sign-in still stands (at most once a minute). An account the provider no longer
|
||||
signs in is signed out of DodoSSH and of every Spelunk on this device; a provider that cannot be reached
|
||||
holds the connection until it can.
|
||||
- **The hostname and port still matter**, though nothing dials them: the host key is pinned under them as it
|
||||
is for every host, and the port is what the agent connects to on the server.
|
||||
- **There is no falling back to a direct dial**, and a refusal is said in Spelunk's terms: a key Spelunk will
|
||||
not take, a key whose role is too low, a server outside the key's organisation, an agent that is not
|
||||
connected, an agent that could not reach the SSH port or is too old to open terminals.
|
||||
- **There is no falling back to a direct dial**, and a refusal is said in Spelunk's terms: signed out, not
|
||||
allowed on that server, a server Spelunk does not know, an agent that is not connected, an agent that could
|
||||
not reach the SSH port or is too old to open terminals.
|
||||
|
||||
**Sign in through Spelunk (no SSH key needed)**, the box under the key in the same card, lets Spelunk log
|
||||
you in instead of an SSH key or password of the host's own. For each connection DodoSSH makes a throwaway
|
||||
Ed25519 key pair in memory and sends the public half with the ticket request, which the API key authorises;
|
||||
Ed25519 key pair in memory and sends the public half with the ticket request, which your sign-in authorises;
|
||||
the agent runs a one-connection `sshd -i` on the server whose only authorised key is that one, and says
|
||||
which account it logs in as (`root`). It is real SSH to the server's real host key, so shells, file
|
||||
transfers and port forwards all work, and the key is gone with the connection — it is never stored,
|
||||
@@ -493,15 +503,14 @@ link, or hands the link to the copy already running, and **connects straight awa
|
||||
carries a credential. The hosts links make live in your personal vault, tagged `spelunk`:
|
||||
|
||||
- If your personal vault has a host tagged `spelunk` for that server on that Spelunk, DodoSSH connects to it.
|
||||
- Otherwise, when you have saved a Spelunk key for that Spelunk under Settings → Security — or a saved host
|
||||
already sends an API key there — DodoSSH saves a new host in your personal vault — named as the link
|
||||
names it, at the link's address (or `spelunk-<server id>`), port 22, signing in through Spelunk with that
|
||||
key, tagged `spelunk` (the tag is made if the vault has none) — and connects to it. It syncs like any host
|
||||
you saved yourself.
|
||||
- **A link from a Spelunk with no key** opens the host editor instead, filled in the same way with sign-in
|
||||
ticked and the tag on, and you choose that Spelunk's API key once and save. Every later link from that
|
||||
Spelunk connects straight away. A link can be sent by anything on this machine, so an API key is never
|
||||
sent to an address you have not sent it to — saving the key under Security is how you say you have.
|
||||
- Otherwise, when this device is signed in to that Spelunk, DodoSSH saves a new host in your personal vault —
|
||||
named as the link names it, at the link's address (or `spelunk-<server id>`), port 22, signing in through
|
||||
Spelunk, tagged `spelunk` (the tag is made if the vault has none) — and connects to it. It syncs like any
|
||||
host you saved yourself.
|
||||
- **A link from a Spelunk this device is not signed in to** opens the host editor instead, filled in the same
|
||||
way with sign-in ticked and the tag on, and offers to sign in to that Spelunk. Sign in, save, and every later
|
||||
link from that Spelunk connects straight away. A link can be sent by anything on this machine, so it never
|
||||
starts a sign-in by itself.
|
||||
|
||||
A host you set up by hand, or one in a team's vault, is left as it is: a link for its server adds a host of
|
||||
its own. A link that arrives while the vault is locked waits for the unlock.
|
||||
|
||||
Reference in new issue
Block a user