Skip to content

Commit 04d4a12

Browse files
feat: Add API key rotate endpoint
1 parent 50dc5fc commit 04d4a12

4 files changed

Lines changed: 67 additions & 4 deletions

File tree

.stats.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
configured_endpoints: 119
2-
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-c98841235b0ece0591f28f7dd424339b6ef2f3e8f539b95b670ae0da2ef43df4.yml
3-
openapi_spec_hash: c1e9456765f0743a333af297d135d5cf
4-
config_hash: 57567e00b41af47cef1b78e51b747aa0
1+
configured_endpoints: 120
2+
openapi_spec_url: https://storage.googleapis.com/stainless-sdk-openapi-specs/kernel/kernel-1f10598afa01d76d22b0ed63685248f482f74c9353cffe1d3e4a3d38da7716cf.yml
3+
openapi_spec_hash: 8936f458bfa681b709e459ca1cc76fb5
4+
config_hash: 03c7e57f268c750e2415831662e95969

api.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -431,6 +431,7 @@ Methods:
431431
- <code title="patch /org/api_keys/{id}">client.APIKeys.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyService.Update">Update</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyUpdateParams">APIKeyUpdateParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKey">APIKey</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
432432
- <code title="get /org/api_keys">client.APIKeys.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyService.List">List</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, query <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyListParams">APIKeyListParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk/packages/pagination">pagination</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk/packages/pagination#OffsetPagination">OffsetPagination</a>[<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKey">APIKey</a>], <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
433433
- <code title="delete /org/api_keys/{id}">client.APIKeys.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyService.Delete">Delete</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>) <a href="https://pkg.go.dev/builtin#error">error</a></code>
434+
- <code title="post /org/api_keys/{id}/rotate">client.APIKeys.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyService.Rotate">Rotate</a>(ctx <a href="https://pkg.go.dev/context">context</a>.<a href="https://pkg.go.dev/context#Context">Context</a>, id <a href="https://pkg.go.dev/builtin#string">string</a>, body <a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#APIKeyRotateParams">APIKeyRotateParams</a>) (\*<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk">kernel</a>.<a href="https://pkg.go.dev/github.com/kernel/kernel-go-sdk#CreatedAPIKey">CreatedAPIKey</a>, <a href="https://pkg.go.dev/builtin#error">error</a>)</code>
434435

435436
# CredentialProviders
436437

apikey.go

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,20 @@ func (r *APIKeyService) Delete(ctx context.Context, id string, opts ...option.Re
110110
return err
111111
}
112112

113+
// Rotate an API key. Issues a new key that copies the name and project of the
114+
// rotated key, and schedules the rotated key to expire after a grace period so
115+
// in-flight callers can swap over. The new plaintext key is returned once.
116+
func (r *APIKeyService) Rotate(ctx context.Context, id string, body APIKeyRotateParams, opts ...option.RequestOption) (res *CreatedAPIKey, err error) {
117+
opts = slices.Concat(r.Options, opts)
118+
if id == "" {
119+
err = errors.New("missing required id parameter")
120+
return nil, err
121+
}
122+
path := fmt.Sprintf("org/api_keys/%s/rotate", id)
123+
err = requestconfig.ExecuteNewRequest(ctx, http.MethodPost, path, body, &res, opts...)
124+
return res, err
125+
}
126+
113127
type APIKey struct {
114128
// Unique API key identifier
115129
ID string `json:"id" api:"required"`
@@ -305,3 +319,21 @@ const (
305319
APIKeyListParamsSortDirectionAsc APIKeyListParamsSortDirection = "asc"
306320
APIKeyListParamsSortDirectionDesc APIKeyListParamsSortDirection = "desc"
307321
)
322+
323+
type APIKeyRotateParams struct {
324+
// Lifetime in days for the new key, up to 3650. Omit to reuse the rotated key's
325+
// original lifetime, or never-expires if it had none.
326+
DaysToExpire param.Opt[int64] `json:"days_to_expire,omitzero"`
327+
// Grace period in days before the rotated key expires. Use 0 to expire it
328+
// immediately. Omit for the default grace period of 7 days.
329+
ExpireInDays param.Opt[int64] `json:"expire_in_days,omitzero"`
330+
paramObj
331+
}
332+
333+
func (r APIKeyRotateParams) MarshalJSON() (data []byte, err error) {
334+
type shadow APIKeyRotateParams
335+
return param.MarshalObject(r, (*shadow)(&r))
336+
}
337+
func (r *APIKeyRotateParams) UnmarshalJSON(data []byte) error {
338+
return apijson.UnmarshalRoot(data, r)
339+
}

apikey_test.go

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -150,3 +150,33 @@ func TestAPIKeyDelete(t *testing.T) {
150150
t.Fatalf("err should be nil: %s", err.Error())
151151
}
152152
}
153+
154+
func TestAPIKeyRotateWithOptionalParams(t *testing.T) {
155+
t.Skip("Mock server tests are disabled")
156+
baseURL := "http://localhost:4010"
157+
if envURL, ok := os.LookupEnv("TEST_API_BASE_URL"); ok {
158+
baseURL = envURL
159+
}
160+
if !testutil.CheckTestServer(t, baseURL) {
161+
return
162+
}
163+
client := kernel.NewClient(
164+
option.WithBaseURL(baseURL),
165+
option.WithAPIKey("My API Key"),
166+
)
167+
_, err := client.APIKeys.Rotate(
168+
context.TODO(),
169+
"id",
170+
kernel.APIKeyRotateParams{
171+
DaysToExpire: kernel.Int(30),
172+
ExpireInDays: kernel.Int(7),
173+
},
174+
)
175+
if err != nil {
176+
var apierr *kernel.Error
177+
if errors.As(err, &apierr) {
178+
t.Log(string(apierr.DumpRequest(true)))
179+
}
180+
t.Fatalf("err should be nil: %s", err.Error())
181+
}
182+
}

0 commit comments

Comments
 (0)