Skip to content

Scope ssh jwt cache by credential - #48

Merged
cretz merged 1 commit into
mainfrom
cretz/ssh-jwt-cache-profile-scope
Aug 5, 2026
Merged

Scope ssh jwt cache by credential#48
cretz merged 1 commit into
mainfrom
cretz/ssh-jwt-cache-profile-scope

Conversation

@cretz

@cretz cretz commented Aug 5, 2026

Copy link
Copy Markdown
Collaborator

🚀 What

  • Scope the SSH JWT cache by resolved credential, so a sign under one credential can't overwrite the token and proxy address another connection is about to read.
  • Ports fix(ssh): scope JWT cache by remote truss#2587, which scopes by remote; the CLI has no remote label in the SSH hostname, so it keys on the credential instead.

💻 How

  • Add auth.Session.CacheIdentity(): profile-<hash>, key-<hash>, or anonymous. Hashed to keep the profile name (an email by default) and the API key out of file paths.
  • sign/proxy pass it through, nesting entries under .jwt-cache/<identity>/.
  • Existing unscoped entries are never read again; sign runs before every connection, so nothing breaks.

🔬 Testing

  • Cache entries don't collide across identities, proxy rejects an entry written under a different credential, and CacheIdentity is stable and leaks neither name nor key.
  • go test ./internal/ssh/... ./internal/auth/... ./internal/cmd/...

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR scopes the on-disk SSH JWT/proxy cache by the resolved auth credential to prevent cross-credential cache collisions (e.g., one ssh sign overwriting the token/proxy address another connection is about to use).

Changes:

  • Added auth.Session.CacheIdentity() to derive a stable, filesystem-safe cache scope for the resolved credential.
  • Updated SSH sign/proxy flow to read/write cache entries under .jwt-cache/<cacheIdentity>/....
  • Added unit and command-level tests to verify cache isolation across credentials and stability/non-leakage of CacheIdentity.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
internal/ssh/ssh.go Nests JWT cache paths under a per-credential cacheIdentity directory and updates save/load helpers.
internal/ssh/ssh_test.go Expands tests to validate cache directory perms and isolation across different cache identities.
internal/ssh/connect.go Threads cacheIdentity through Sign/Proxy and scopes cache read/write to that identity.
internal/cmd/command.ssh.go Resolves cacheIdentity from the current session and passes it into SSH sign/proxy commands.
internal/cmd/command.ssh_test.go Adds an integration-style test ensuring proxy does not read cache written under a different credential.
internal/auth/transport.go Introduces Session.CacheIdentity() using hashed identifiers for profile- and key-based sessions.
internal/auth/transport_test.go Adds tests ensuring CacheIdentity is stable, scoped, and does not leak raw profile name or key.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread internal/ssh/connect.go
Comment thread internal/ssh/ssh.go
@cretz
cretz marked this pull request as ready for review August 5, 2026 17:45
Comment thread internal/ssh/ssh.go
func saveJWT(d string, h hostname, jwt, proxyAddr string) error {
if err := os.MkdirAll(filepath.Join(d, ".jwt-cache"), 0o700); err != nil {
func saveJWT(d, cacheIdentity string, h hostname, jwt, proxyAddr string) error {
if err := os.MkdirAll(filepath.Join(d, ".jwt-cache", cacheIdentity), 0o700); err != nil {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Literal jwt-cache appears in two places, can you instread use soemthing lieke

file = jwtCachePath(...)
os.MkdirAll(Dir(file))

Copy link
Copy Markdown
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The two places building this dir probably not worth a new one-line method, not much logic here

@cretz
cretz merged commit 0661792 into main Aug 5, 2026
5 checks passed
@cretz
cretz deleted the cretz/ssh-jwt-cache-profile-scope branch August 5, 2026 18:44
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants