A login moves its node; an API key is added from any node, sealed (novox/hq ADR 0209)
The manager binds the node a login was adopted from to that login's licence, switching it if it was bound to another; serves public_key; adopt takes a key sealed to it. claude-code gains claude_code_add_api_key: read a file on this node, seal, hand to adopt, remove the file, optionally switch here.
This commit is contained in:
@@ -362,3 +362,40 @@ func TestABadEntryIsRefusedBeforeAnythingIsPut(t *testing.T) {
|
||||
t.Fatal("another node's key changed this one")
|
||||
}
|
||||
}
|
||||
|
||||
// An API key goes to the manager sealed to its key, never in the clear, and its file is gone afterwards.
|
||||
func TestAnAPIKeyIsHandedOverSealedAndItsFileRemoved(t *testing.T) {
|
||||
p, _ := node(t, "laptop")
|
||||
manager, _ := GenerateKeyPair()
|
||||
file := filepath.Join(p.Home, "api-key")
|
||||
writeFile(t, file, "sk-ant-api03-secret\n")
|
||||
var sent []string
|
||||
ask := func(address string, args any) (json.RawMessage, error) {
|
||||
raw, _ := json.Marshal(args)
|
||||
sent = append(sent, address+" "+string(raw))
|
||||
switch address {
|
||||
case "seat:anthropic-licence-manager.public_key":
|
||||
return json.Marshal(map[string]any{"public_key": manager.PublicKey})
|
||||
case "seat:anthropic-licence-manager.adopt":
|
||||
box := args.(map[string]any)["sealed"].(SealedBox)
|
||||
if key, err := Open(box, manager.PrivateKey); err != nil || key != "sk-ant-api03-secret" {
|
||||
t.Fatalf("the manager opened %q, %v", key, err)
|
||||
}
|
||||
return json.Marshal(map[string]any{"adopted": true})
|
||||
case "seat:anthropic-licence-manager.switch":
|
||||
return json.Marshal(map[string]any{"licence": "api"})
|
||||
}
|
||||
t.Fatalf("asked %s", address)
|
||||
return nil, nil
|
||||
}
|
||||
out, err := AddAPIKey(p, "api", file, true, ask)
|
||||
if err != nil || out["file"] != "removed" || out["switched"] == nil {
|
||||
t.Fatalf("%v %v", out, err)
|
||||
}
|
||||
if _, err := os.Stat(file); !os.IsNotExist(err) {
|
||||
t.Fatal("the key file is still there")
|
||||
}
|
||||
if strings.Contains(strings.Join(sent, "\n"), "sk-ant") {
|
||||
t.Fatalf("the key crossed in the clear: %v", sent)
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user