Documentation
¶
Overview ¶
Package client is the public Go SDK for the Wardyn control plane. It uses internal/types as the shared JSON source of truth and adds zero non-stdlib dependencies so it can be embedded in external tooling without friction. The in-repo `wardyn` CLI uses THIS client directly (there is no second transport); it maps APIError to process exit codes and prints APIError.Error(), which unwraps the server's {"error":...} envelope into a human-readable message.
Coverage ¶
The SDK covers these wardynd public route families (the ones external tooling automates); it is a curated subset, NOT a 1:1 mirror of every route:
- runs: CreateRun, GetRun, ListRuns, ListGrants, KillRun, SynthesizeProfile
- approvals: ListApprovals, Approve, Deny
- policies: CreatePolicy, GetPolicy, ListPolicies, UpdatePolicy, DeletePolicy
- workspaces: CreateWorkspace, GetWorkspace, ListWorkspaces, UpdateWorkspace, DeleteWorkspace, ScanWorkspace, VerifyWorkspace, RecordWorkspaceTask
- audit: AuditEvents, RecentAuditEvents
- secrets: ListSecrets, SetSecret, DeleteSecret
- site-config: GetSiteConfig, PutSiteConfig
- setup: SetupStatus
- identity: Me
- health: Healthz
NOT covered (drive these with the CLI or raw HTTP): the AI Run Composer (/runs/compose*), preflight, attach WebSocket / attach-ticket, harness-login device flow, and the agent-facing /internal/* mint & decision endpoints. TestClientCoversRouteFamilies pins that every family listed above has a method.
Pagination ¶
The list endpoints and the audit trail accept an optional ListOpts (variadic, so existing zero-arg calls are unchanged) that sends ?limit=&offset=. A page may be truncated (the server sets X-Wardyn-Truncated); re-request with Offset advanced by len(page) to page forward.
Usage:
c := client.New("https://wardyn.example.com", "admin-token")
run, err := c.CreateRun(ctx, client.CreateRunRequest{
Agent: "claude-code",
Repo: "org/repo",
Task: "fix issue #42",
})
Index ¶
- Constants
- type APIError
- type ActorType
- type AgentRun
- type ApprovalKind
- type ApprovalRequest
- type ApprovalState
- type AuditEvent
- type Client
- func (c *Client) Approve(ctx context.Context, id uuid.UUID, reason string) (types.ApprovalRequest, error)
- func (c *Client) AuditEvents(ctx context.Context, runID uuid.UUID, opts ...ListOpts) ([]types.AuditEvent, error)
- func (c *Client) ConnectManagedSubscription(ctx context.Context, provider, token string) error
- func (c *Client) CreatePolicy(ctx context.Context, req PolicyRequest) (types.RunPolicy, error)
- func (c *Client) CreateRun(ctx context.Context, req CreateRunRequest) (types.AgentRun, error)
- func (c *Client) CreateWorkspace(ctx context.Context, req WorkspaceRequest) (types.Workspace, error)
- func (c *Client) DeletePolicy(ctx context.Context, id uuid.UUID) error
- func (c *Client) DeleteSecret(ctx context.Context, name string) error
- func (c *Client) DeleteWorkspace(ctx context.Context, id uuid.UUID) error
- func (c *Client) Deny(ctx context.Context, id uuid.UUID, reason string) (types.ApprovalRequest, error)
- func (c *Client) DisconnectManagedSubscription(ctx context.Context, provider string) error
- func (c *Client) GetPolicy(ctx context.Context, id uuid.UUID) (types.RunPolicy, error)
- func (c *Client) GetRun(ctx context.Context, id uuid.UUID) (types.AgentRun, error)
- func (c *Client) GetSiteConfig(ctx context.Context) (types.SiteConfig, error)
- func (c *Client) GetWorkspace(ctx context.Context, id uuid.UUID) (types.Workspace, error)
- func (c *Client) Healthz(ctx context.Context) (json.RawMessage, error)
- func (c *Client) KillRun(ctx context.Context, id uuid.UUID) (KillRunResponse, error)
- func (c *Client) ListApprovals(ctx context.Context, state types.ApprovalState, opts ...ListOpts) ([]types.ApprovalRequest, error)
- func (c *Client) ListGrants(ctx context.Context, runID uuid.UUID) ([]types.CredentialGrant, error)
- func (c *Client) ListPolicies(ctx context.Context, opts ...ListOpts) ([]types.RunPolicy, error)
- func (c *Client) ListRuns(ctx context.Context, opts ...ListOpts) ([]types.AgentRun, error)
- func (c *Client) ListSecrets(ctx context.Context) ([]string, error)
- func (c *Client) ListWorkspaces(ctx context.Context, opts ...ListOpts) ([]types.Workspace, error)
- func (c *Client) Me(ctx context.Context) (json.RawMessage, error)
- func (c *Client) PutSiteConfig(ctx context.Context, cfg types.SiteConfig) (types.SiteConfig, error)
- func (c *Client) RecentAuditEvents(ctx context.Context, opts ...ListOpts) ([]types.AuditEvent, error)
- func (c *Client) RecordWorkspaceTask(ctx context.Context, wsID uuid.UUID, taskKey string) (RecordTaskResult, error)
- func (c *Client) ScanWorkspace(ctx context.Context, id uuid.UUID) (json.RawMessage, error)
- func (c *Client) SetSecret(ctx context.Context, name, value string) error
- func (c *Client) SetupStatus(ctx context.Context) (json.RawMessage, error)
- func (c *Client) SynthesizeProfile(ctx context.Context, runID uuid.UUID) (ProfileResult, error)
- func (c *Client) UpdatePolicy(ctx context.Context, id uuid.UUID, req PolicyRequest) (types.RunPolicy, error)
- func (c *Client) UpdateWorkspace(ctx context.Context, id uuid.UUID, req WorkspaceRequest) (types.Workspace, error)
- func (c *Client) VerifyWorkspace(ctx context.Context, id uuid.UUID) (json.RawMessage, error)
- type ConfinementClass
- type CreateRunRequest
- type CredentialGrant
- type GrantKind
- type GrantSpec
- type KillRunResponse
- type ListOpts
- type PolicyRequest
- type ProfileResult
- type RecordTaskResult
- type RunPolicy
- type RunPolicySpec
- type RunState
- type WorkspaceMount
- type WorkspaceRequest
Constants ¶
const ( ApprovalPending = types.ApprovalPending ApprovalApproved = types.ApprovalApproved ApprovalDenied = types.ApprovalDenied ApprovalExpired = types.ApprovalExpired )
ApprovalState values. ListApprovals accepts one of these (or "" for all states).
const ( RunPending = types.RunPending RunStarting = types.RunStarting RunRunning = types.RunRunning RunWaiting = types.RunWaiting RunStopped = types.RunStopped RunArchived = types.RunArchived RunFailed = types.RunFailed RunKilled = types.RunKilled RunCompleted = types.RunCompleted )
RunState values.
ConfinementClass values.
const ( GrantGitHubToken = types.GrantGitHubToken GrantCloudSTS = types.GrantCloudSTS GrantAPIKey = types.GrantAPIKey )
GrantKind values.
const ( ApprovalCredential = types.ApprovalCredential ApprovalEgressDomain = types.ApprovalEgressDomain ApprovalToolCall = types.ApprovalToolCall )
ApprovalKind values.
const ( ActorHuman = types.ActorHuman ActorAgent = types.ActorAgent ActorSystem = types.ActorSystem )
ActorType values.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type APIError ¶
type APIError struct {
// Status is the HTTP status code, e.g. 404.
Status int
// Body is the raw server response body (capped at 2048 bytes).
Body string
}
APIError is returned when the server responds with a non-2xx status code. Status is the HTTP status code; Body is the raw response body (trimmed to 2 KiB) for diagnostic display. Callers may use errors.As to extract it.
type AgentRun ¶
AgentRun is one governed execution of a coding agent. Returned by CreateRun, GetRun, and ListRuns.
type ApprovalKind ¶
type ApprovalKind = types.ApprovalKind
ApprovalKind enumerates what a human is being asked to approve (ApprovalRequest.Kind).
type ApprovalRequest ¶
type ApprovalRequest = types.ApprovalRequest
ApprovalRequest is a human-in-the-loop approval gate. Returned by ListApprovals, Approve, and Deny.
type ApprovalState ¶
type ApprovalState = types.ApprovalState
ApprovalState is the approval lifecycle state; ListApprovals filters on it (ApprovalRequest.State).
type AuditEvent ¶
type AuditEvent = types.AuditEvent
AuditEvent is one append-only audit record. Returned by AuditEvents.
type Client ¶
type Client struct {
// BaseURL is the wardynd root, e.g. "https://wardyn.example.com".
// A trailing slash is stripped automatically.
BaseURL string
// Token is the admin bearer token configured in wardynd (AdminToken).
Token string
// HTTPClient, when non-nil, is used instead of http.DefaultClient.
HTTPClient *http.Client
// Principal, when non-empty, is sent as the X-Wardyn-Principal header.
// This overrides the server-side principal attribution for multi-user dev;
// in production the token's subject is used instead.
Principal string
}
Client is the Wardyn SDK client. Construct it with New or by filling the fields directly. BaseURL and Token are required; HTTPClient defaults to http.DefaultClient when nil.
All methods accept a context; the context controls cancellation and deadline for the underlying HTTP call.
func (*Client) Approve ¶
func (c *Client) Approve(ctx context.Context, id uuid.UUID, reason string) (types.ApprovalRequest, error)
Approve transitions an approval request to APPROVED. reason is optional; pass an empty string to omit it. Returns 409/APIError when the approval has already been decided. Returns 404/APIError when the approval does not exist.
func (*Client) AuditEvents ¶
func (c *Client) AuditEvents(ctx context.Context, runID uuid.UUID, opts ...ListOpts) ([]types.AuditEvent, error)
AuditEvents returns the append-only audit trail for the specified run in chronological (seq ASC) order. run_id is required by the server; a zero UUID is rejected with 400. Pass a ListOpts to page a long trail: a truncated page (server sets X-Wardyn-Truncated) is walked forward with Offset += len(page), which reaches the terminal run.complete event under ASC order.
func (*Client) ConnectManagedSubscription ¶ added in v0.4.0
ConnectManagedSubscription stores a captured provider setup-token so the proxy injects it into every eligible run (never resident in the sandbox). The value is write-only. PUT /api/v1/setup/harness-credential/{provider}.
func (*Client) CreatePolicy ¶
CreatePolicy validates and persists a new policy. Returns the created RunPolicy (status 201) on success; 400 on an invalid name or spec.
func (*Client) CreateRun ¶
CreateRun submits a new agent run to the control plane. Returns the created AgentRun (state PENDING or RUNNING) on success. Status 201 on success; 400 on validation failure; 422 on policy/confinement mismatch; 503 when the runner is unavailable.
func (*Client) CreateWorkspace ¶ added in v0.3.1
func (c *Client) CreateWorkspace(ctx context.Context, req WorkspaceRequest) (types.Workspace, error)
CreateWorkspace onboards a new workspace (status pending_scan). Returns the created row (201); 400 on an invalid body/source.
func (*Client) DeletePolicy ¶
DeletePolicy removes a policy by id. Returns nil on success (204); 404/APIError when the policy does not exist.
func (*Client) DeleteSecret ¶
DeleteSecret removes a named secret. DELETE /api/v1/secrets/{name}. Returns 403 for a reserved platform-internal name.
func (*Client) DeleteWorkspace ¶ added in v0.3.1
DeleteWorkspace removes a workspace by id. Returns nil (204); 404 when unknown.
func (*Client) Deny ¶
func (c *Client) Deny(ctx context.Context, id uuid.UUID, reason string) (types.ApprovalRequest, error)
Deny transitions an approval request to DENIED (fail closed). reason is optional; pass an empty string to omit it. Returns 409/APIError when the approval has already been decided. Returns 404/APIError when the approval does not exist.
func (*Client) DisconnectManagedSubscription ¶ added in v0.4.0
DisconnectManagedSubscription removes a provider's stored managed subscription token. DELETE /api/v1/setup/harness-credential/{provider}.
func (*Client) GetPolicy ¶
GetPolicy fetches a single RunPolicy by its UUID. Returns 404/APIError when the policy does not exist.
func (*Client) GetRun ¶
GetRun fetches a single AgentRun by its UUID. Returns 404/APIError when the run does not exist.
func (*Client) GetSiteConfig ¶ added in v0.3.1
GetSiteConfig returns the operator-wide site config. GET /api/v1/site-config.
func (*Client) GetWorkspace ¶ added in v0.3.1
GetWorkspace fetches a single workspace by id. Returns 404/APIError when unknown.
func (*Client) Healthz ¶ added in v0.3.1
Healthz returns the control-plane health payload as raw JSON. GET /healthz (note: NOT under /api/v1, and unauthenticated).
func (*Client) KillRun ¶
KillRun initiates the kill sequence for a run: sandbox teardown, identity revocation, credential revocation, then state transition to KILLED. Returns 202/Accepted with the final state on success. Returns 404/APIError when the run does not exist.
func (*Client) ListApprovals ¶
func (c *Client) ListApprovals(ctx context.Context, state types.ApprovalState, opts ...ListOpts) ([]types.ApprovalRequest, error)
ListApprovals returns approval requests filtered by state. Pass an empty string to return all states. Valid states: "PENDING", "APPROVED", "DENIED", "EXPIRED" (types.ApprovalState).
func (*Client) ListGrants ¶
ListGrants returns the credential-grant eligibility records for a run. These are eligibility records (what the run MAY request), not issued credentials — some may never be minted. Returns 404/APIError when the run does not exist.
func (*Client) ListPolicies ¶
ListPolicies returns run policies in reverse creation order. Pass a ListOpts to page.
func (*Client) ListSecrets ¶
ListSecrets returns the managed secret NAMES (never values). Reserved platform-internal keys are excluded server-side. GET /api/v1/secrets, which responds {"names":[...]}.
func (*Client) ListWorkspaces ¶ added in v0.3.1
ListWorkspaces returns onboarded workspaces in reverse creation order. Pass a ListOpts to page.
func (*Client) Me ¶ added in v0.3.1
Me returns the caller's resolved identity/attribution as raw JSON. GET /api/v1/me.
func (*Client) PutSiteConfig ¶ added in v0.3.1
func (c *Client) PutSiteConfig(ctx context.Context, cfg types.SiteConfig) (types.SiteConfig, error)
PutSiteConfig replaces the operator-wide site config and returns the persisted value. PUT /api/v1/site-config.
func (*Client) RecentAuditEvents ¶ added in v0.3.1
func (c *Client) RecentAuditEvents(ctx context.Context, opts ...ListOpts) ([]types.AuditEvent, error)
RecentAuditEvents returns the newest-first global audit feed (all runs) — the SIEM-style tail the Audit view renders. Pass a ListOpts to page.
func (*Client) RecordWorkspaceTask ¶ added in v0.3.1
func (c *Client) RecordWorkspaceTask(ctx context.Context, wsID uuid.UUID, taskKey string) (RecordTaskResult, error)
RecordWorkspaceTask launches a named open (allow-all egress) recording session for a workspace via the import pipeline — the operator attaches, does the real activity, and stops the run to capture what it actually used. POST /api/v1/workspaces/{id}/record with body {"task_key": name}. Returns 202 with the launched run; 503 when no runner is wired; 409 while another import step is live.
func (*Client) ScanWorkspace ¶ added in v0.3.1
ScanWorkspace triggers the workspace scan (populates the least-privilege profile). The reply shape varies (a completed profile vs an accepted async run), so it is returned as raw JSON. POST /api/v1/workspaces/{id}/scan.
func (*Client) SetSecret ¶
SetSecret stores (or overwrites) a named secret. The value is write-only — no API path ever returns it. PUT /api/v1/secrets/{name} with body {"value":...}. Returns 400 on an invalid name, 403 for a reserved platform-internal name.
func (*Client) SetupStatus ¶ added in v0.3.1
SetupStatus returns the first-run setup checklist as raw JSON (the response is a server-internal struct not exported through internal/types). GET /api/v1/setup/status.
func (*Client) SynthesizeProfile ¶ added in v0.3.1
SynthesizeProfile runs Recording Mode synthesis for a run: from its already- captured audit / egress / ground-truth events the server proposes a tightened, reusable RunPolicy ("sandbox profile"). ADVISORY and READ-ONLY — it mints nothing and persists no policy (save the proposal via CreatePolicy). POST /api/v1/runs/{id}/profile. Returns 404 when the run does not exist.
func (*Client) UpdatePolicy ¶
func (c *Client) UpdatePolicy(ctx context.Context, id uuid.UUID, req PolicyRequest) (types.RunPolicy, error)
UpdatePolicy validates and replaces an existing policy's name and spec. Returns the updated RunPolicy on success; 404 when unknown; 400 when invalid.
func (*Client) UpdateWorkspace ¶ added in v0.3.1
func (c *Client) UpdateWorkspace(ctx context.Context, id uuid.UUID, req WorkspaceRequest) (types.Workspace, error)
UpdateWorkspace replaces a workspace's editable identity fields. Returns the updated row; 404 when unknown; 400 when invalid.
func (*Client) VerifyWorkspace ¶ added in v0.3.1
VerifyWorkspace launches the import verify run for a workspace. Returns the raw accepted-run reply. POST /api/v1/workspaces/{id}/verify; 503 when no runner is wired; 409 while another import step is live.
type ConfinementClass ¶
type ConfinementClass = types.ConfinementClass
ConfinementClass declares how strongly a sandbox confines an agent (AgentRun.ConfinementClass, RunPolicySpec.MinConfinementClass).
type CreateRunRequest ¶
type CreateRunRequest struct {
Agent string `json:"agent"`
Repo string `json:"repo"`
Task string `json:"task,omitempty"`
PolicyID *uuid.UUID `json:"policy_id,omitempty"`
// ConfinementClass, when set, requests a specific confinement class
// ("CC1"/"CC2"/"CC3"). Empty inherits the policy minimum; an unknown
// non-empty value is rejected by the server with 400.
ConfinementClass string `json:"confinement_class,omitempty"`
// Interactive requests an interactive run: the sandbox comes up idle (no
// agent task is exec'd) so a human can attach to it (wardyn attach <id>).
// Pair with a never-reap policy (AutoStopAfterSec < 0) or the idle reaper
// will stop the idle sandbox. Task is ignored for an interactive run.
Interactive bool `json:"interactive,omitempty"`
// InlinePolicy, when set, supplies the run's full RunPolicySpec INLINE
// instead of referencing a stored PolicyID. It is MUTUALLY EXCLUSIVE with
// PolicyID (the server rejects both with 400); neither set falls back to the
// configured default. The server validates it exactly like a stored policy
// (mounts pass the same deny-list; api_key grants must reference an existing
// secret) and attaches it with no stored policy id.
InlinePolicy *RunPolicySpec `json:"inline_policy,omitempty"`
// DevcontainerRepo, when set AND an image builder is wired (WARDYN_ENVBUILD),
// triggers a devcontainer build of that git repo whose resulting image becomes
// the sandbox image. Ignored (degrades to the convention image) when no builder
// is wired. Mutually exclusive with Image.
DevcontainerRepo string `json:"devcontainer_repo,omitempty"`
// DevcontainerRef is the optional git ref (branch/tag/sha) to build for
// DevcontainerRepo.
DevcontainerRef string `json:"devcontainer_ref,omitempty"`
// Image, when set, is a USER-supplied base image (Bring Your Own Image); the
// server wraps it with the runner tools via a trusted finalize stage and
// requires an image builder to be wired (WARDYN_ENVBUILD) — an explicit
// Image with no builder wired is a hard 400 rather than a silent fallback.
// Mutually exclusive with DevcontainerRepo.
Image string `json:"image,omitempty"`
// TaskMode selects how a non-interactive run executes Task: "" / "harness"
// (default) runs the agent harness; "exec" runs Task as a plain shell
// command in the same governed sandbox (no agent, no LLM credentials — the
// BYOA/CI lane; see docs/CI.md). Ignored for an interactive run.
TaskMode string `json:"task_mode,omitempty"`
// ComposeSessionID correlates a run launched from the AI Run Composer back
// to the compose conversation that produced it. It is stamped into the
// run.create audit event, so filtering the audit feed on it reconstructs the
// whole compose→launch trail. Purely a correlation label: it grants nothing
// and is not validated server-side.
ComposeSessionID string `json:"compose_session_id,omitempty"`
}
CreateRunRequest is the body for POST /api/v1/runs.
type CredentialGrant ¶
type CredentialGrant = types.CredentialGrant
CredentialGrant is a credential-grant eligibility record. Returned by ListGrants.
type GrantSpec ¶
GrantSpec is a credential scope description carried in RunPolicySpec.EligibleGrants.
type KillRunResponse ¶
KillRunResponse is the body returned by POST /api/v1/runs/{id}/kill.
type ListOpts ¶ added in v0.3.1
ListOpts carries the server's ?limit=&offset= pagination for the list and audit endpoints. The zero value sends nothing, so the server applies its default page size. Methods take it variadically; pass at most one.
type PolicyRequest ¶
type PolicyRequest struct {
Name string `json:"name"`
Spec types.RunPolicySpec `json:"spec"`
}
PolicyRequest is the body for POST/PUT /api/v1/policies. Name is required; Spec is validated server-side before persistence (a bad spec is rejected with 400, fail closed).
type ProfileResult ¶ added in v0.3.1
type ProfileResult struct {
Proposed struct {
InlinePolicy RunPolicySpec `json:"inline_policy"`
} `json:"proposed"`
OverallRisk string `json:"overall_risk"`
Observations struct {
Domains []struct {
Host string `json:"host"`
Methods []string `json:"methods"`
} `json:"domains"`
Anomalies []string `json:"anomalies"`
} `json:"observations"`
Warnings []string `json:"warnings"`
}
ProfileResult is the decoded POST /api/v1/runs/{id}/profile reply (Recording Mode): the synthesized least-privilege sandbox profile plus the observations it was built from. Only the fields callers render/save are modeled — the full server response (profileResponse) additionally carries a per-item risk breakdown the SDK does not surface.
type RecordTaskResult ¶ added in v0.3.1
type RecordTaskResult struct {
RecordRunID string `json:"record_run_id"`
TaskKey string `json:"task_key"`
Mode string `json:"mode"`
Detail string `json:"detail"`
Warnings []string `json:"warnings"`
}
RecordTaskResult is the decoded POST /api/v1/workspaces/{id}/record reply: the launched open-egress recording run plus the resolved session key/mode.
type RunPolicy ¶
RunPolicy is a declarative policy attached to runs. Returned by the policy methods (ListPolicies, GetPolicy, CreatePolicy, UpdatePolicy).
type RunPolicySpec ¶
type RunPolicySpec = types.RunPolicySpec
RunPolicySpec is the policy body carried in PolicyRequest.Spec. As a true `=` alias it carries the full wire surface, including AllowAllEgress (json:"allow_all_egress,omitempty") for the "allow all (deny-list only)" egress mode — no separate SDK struct to keep in sync.
type WorkspaceMount ¶
type WorkspaceMount = types.WorkspaceMount
WorkspaceMount is an operator/policy-controlled host bind mount carried in RunPolicySpec.WorkspaceMounts.
type WorkspaceRequest ¶ added in v0.3.1
type WorkspaceRequest struct {
Name string `json:"name"`
Kind types.WorkspaceKind `json:"kind"`
Source string `json:"source"`
Ref string `json:"ref,omitempty"`
DefaultTarget string `json:"default_target,omitempty"`
// Writable opts the workspace into a READ-WRITE mount for import Record/Verify
// runs; omitted/false is read-only (the safe default).
Writable bool `json:"writable,omitempty"`
}
WorkspaceRequest is the body for POST/PUT /api/v1/workspaces. Name/Kind/Source are required; the server validates Source with the same deny-list the run path uses (local_dir bind-mount safety, repo slug/URL shape) before persisting.