feat: Phase 2 Workstream 3 — Go SDK (github.com/sentryagent/idp-sdk-go)
Single-package agentidp SDK in sdk-go/: - AgentIdPClient composing AgentRegistryClient, CredentialClient, TokenServiceClient, AuditClient — all 14 endpoints covered - Goroutine-safe TokenManager (sync.Mutex) with 60s refresh buffer - AgentIdPError implementing error interface with Code/HTTPStatus/Details - Context-aware: all service methods take context.Context as first arg - doRequest shared helper; token endpoints use form-encoded POST directly - go vet: 0 warnings | staticcheck: 0 warnings - go test ./...: 37/37 passed | coverage: 81.0% (>80% gate) Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
93
sdk-go/credentials.go
Normal file
93
sdk-go/credentials.go
Normal file
@@ -0,0 +1,93 @@
|
||||
package agentidp
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"net/http"
|
||||
"net/url"
|
||||
"strings"
|
||||
)
|
||||
|
||||
// CredentialClient provides methods for the Credential Management API endpoints.
|
||||
type CredentialClient struct {
|
||||
baseURL string
|
||||
getToken func(ctx context.Context) (string, error)
|
||||
httpClient *http.Client
|
||||
}
|
||||
|
||||
func newCredentialClient(baseURL string, getToken func(ctx context.Context) (string, error), httpClient *http.Client) *CredentialClient {
|
||||
return &CredentialClient{
|
||||
baseURL: strings.TrimRight(baseURL, "/"),
|
||||
getToken: getToken,
|
||||
httpClient: httpClient,
|
||||
}
|
||||
}
|
||||
|
||||
// GenerateCredential creates a new credential for the given agent.
|
||||
// POST /api/v1/agents/:id/credentials → 201 CredentialWithSecret
|
||||
func (c *CredentialClient) GenerateCredential(ctx context.Context, agentID string) (*CredentialWithSecret, error) {
|
||||
token, err := c.getToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
var cred CredentialWithSecret
|
||||
if err := doRequest(ctx, c.httpClient, http.MethodPost, c.baseURL+"/api/v1/agents/"+agentID+"/credentials", struct{}{}, token, &cred); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cred, nil
|
||||
}
|
||||
|
||||
// ListCredentials returns a paginated list of credentials for the given agent.
|
||||
// GET /api/v1/agents/:id/credentials → 200 PaginatedCredentials
|
||||
func (c *CredentialClient) ListCredentials(ctx context.Context, agentID string, page, limit int) (*PaginatedCredentials, error) {
|
||||
token, err := c.getToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawURL := c.baseURL + "/api/v1/agents/" + agentID + "/credentials"
|
||||
q := url.Values{}
|
||||
if page > 0 {
|
||||
q.Set("page", fmt.Sprintf("%d", page))
|
||||
}
|
||||
if limit > 0 {
|
||||
q.Set("limit", fmt.Sprintf("%d", limit))
|
||||
}
|
||||
if len(q) > 0 {
|
||||
rawURL += "?" + q.Encode()
|
||||
}
|
||||
var result PaginatedCredentials
|
||||
if err := doRequest(ctx, c.httpClient, http.MethodGet, rawURL, nil, token, &result); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// RotateCredential generates a new secret for the given credential.
|
||||
// POST /api/v1/agents/:id/credentials/:credId/rotate → 200 CredentialWithSecret
|
||||
func (c *CredentialClient) RotateCredential(ctx context.Context, agentID, credentialID string) (*CredentialWithSecret, error) {
|
||||
token, err := c.getToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawURL := c.baseURL + "/api/v1/agents/" + agentID + "/credentials/" + credentialID + "/rotate"
|
||||
var cred CredentialWithSecret
|
||||
if err := doRequest(ctx, c.httpClient, http.MethodPost, rawURL, struct{}{}, token, &cred); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cred, nil
|
||||
}
|
||||
|
||||
// RevokeCredential permanently revokes a credential.
|
||||
// DELETE /api/v1/agents/:id/credentials/:credId → 200 Credential
|
||||
func (c *CredentialClient) RevokeCredential(ctx context.Context, agentID, credentialID string) (*Credential, error) {
|
||||
token, err := c.getToken(ctx)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
rawURL := c.baseURL + "/api/v1/agents/" + agentID + "/credentials/" + credentialID
|
||||
var cred Credential
|
||||
if err := doRequest(ctx, c.httpClient, http.MethodDelete, rawURL, nil, token, &cred); err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return &cred, nil
|
||||
}
|
||||
Reference in New Issue
Block a user