fix(terraform): omit empty key_alias from /key/update payload

/key/generate leaves key_alias out when it is unset, but UpdateKey built its
payload by hand and always sent it, so updating a key that has no alias wrote
key_alias: "" to the database. The proxy then treats "" as a real alias and
_enforce_unique_key_alias rejects the next aliasless key's update with a 400
saying the alias already exists.

Send key_alias only when it is set, matching /key/generate.
This commit is contained in:
Julian Löffler 2026-09-11 09:24:09 +02:00
parent 9a715df212
commit c64f6429ec
No known key found for this signature in database
2 changed files with 36 additions and 1 deletions

View file

@ -126,13 +126,19 @@ func (c *Client) UpdateKey(key *Key) (*Key, error) {
updateData := map[string]interface{}{
"key": key.Key,
"team_id": key.TeamID,
"key_alias": key.KeyAlias,
"aliases": key.Aliases,
"permissions": key.Permissions,
"model_max_budget": key.ModelMaxBudget,
"blocked": key.Blocked,
}
// /key/generate omits an empty key_alias, so sending "" here would store an
// alias the key never had and collide with every other aliasless key on the
// proxy's uniqueness check.
if key.KeyAlias != "" {
updateData["key_alias"] = key.KeyAlias
}
// The proxy keeps the stored metadata only when the field is absent, so nil means omit.
if key.Metadata != nil {
updateData["metadata"] = key.Metadata

View file

@ -319,6 +319,35 @@ func TestUpdateKeyOmitsEmptyBudgetDuration(t *testing.T) {
}
}
// /key/generate omits an empty key_alias, so an update that sends "" stores an
// alias the key never had, and the proxy then 400s every other aliasless key on
// its unique-alias check.
func TestUpdateKeyOmitsEmptyKeyAlias(t *testing.T) {
var captured map[string]interface{}
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
body, _ := io.ReadAll(r.Body)
json.Unmarshal(body, &captured)
w.Header().Set("Content-Type", "application/json")
w.Write([]byte(`{"key": "sk-test"}`))
}))
defer srv.Close()
client := NewClient(srv.URL, "test-key", true)
if _, err := client.UpdateKey(&Key{Key: "sk-test"}); err != nil {
t.Fatalf("UpdateKey returned error: %v", err)
}
if _, present := captured["key_alias"]; present {
t.Errorf("update payload contains empty key_alias: %v", captured["key_alias"])
}
if _, err := client.UpdateKey(&Key{Key: "sk-test", KeyAlias: "alias-1"}); err != nil {
t.Fatalf("UpdateKey returned error: %v", err)
}
if captured["key_alias"] != "alias-1" {
t.Errorf("key_alias = %v, want alias-1", captured["key_alias"])
}
}
func TestResourceKeyUpdateFailureKeepsPriorState(t *testing.T) {
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.Header().Set("Content-Type", "application/json")