From ac597a53a0d8276c77d2a50b658e2560fd4f44ae Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Thu, 16 Mar 2023 11:33:12 -0500 Subject: [PATCH 01/29] feat: dbauthz always on, out of experimental --- coderd/coderd.go | 15 +++++++-------- coderd/coderdtest/coderdtest.go | 14 ++++++-------- 2 files changed, 13 insertions(+), 16 deletions(-) diff --git a/coderd/coderd.go b/coderd/coderd.go index 3a82a2a50bf36..cebf9c33d8494 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -163,6 +163,12 @@ func New(options *Options) *API { if options == nil { options = &Options{} } + + options.Database = dbauthz.New( + options.Database, + options.Authorizer, + options.Logger.Named("authz_querier"), + ) experiments := initExperiments( options.Logger, options.DeploymentValues.Experiments.Value(), ) @@ -210,14 +216,7 @@ func New(options *Options) *API { if options.Auditor == nil { options.Auditor = audit.NewNop() } - // TODO: remove this once we promote authz_querier out of experiments. - if experiments.Enabled(codersdk.ExperimentAuthzQuerier) { - options.Database = dbauthz.New( - options.Database, - options.Authorizer, - options.Logger.Named("authz_querier"), - ) - } + if options.SetUserGroups == nil { options.SetUserGroups = func(context.Context, database.Store, uuid.UUID, []string) error { return nil } } diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index 987f912c35165..274d044175179 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -22,7 +22,6 @@ import ( "net/http" "net/http/httptest" "net/url" - "os" "regexp" "strconv" "strings" @@ -184,15 +183,14 @@ func NewOptions(t *testing.T, options *Options) (func(http.Handler), context.Can if options.Database == nil { options.Database, options.Pubsub = dbtestutil.NewDB(t) } - // TODO: remove this once we're ready to enable authz querier by default. - if strings.Contains(os.Getenv("CODER_EXPERIMENTS_TEST"), string(codersdk.ExperimentAuthzQuerier)) { - if options.Authorizer == nil { - options.Authorizer = &RecordingAuthorizer{ - Wrapped: rbac.NewCachingAuthorizer(prometheus.NewRegistry()), - } + options.Database = dbauthz.New(options.Database, options.Authorizer, slogtest.Make(t, nil).Leveled(slog.LevelDebug)) + + if options.Authorizer == nil { + options.Authorizer = &RecordingAuthorizer{ + Wrapped: rbac.NewCachingAuthorizer(prometheus.NewRegistry()), } - options.Database = dbauthz.New(options.Database, options.Authorizer, slogtest.Make(t, nil).Leveled(slog.LevelDebug)) } + if options.DeploymentValues == nil { options.DeploymentValues = DeploymentValues(t) } From 7118bf09a332faf477b77de011950f163cd50b65 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 10:12:46 -0500 Subject: [PATCH 02/29] Add ability to do rbac checks in unit tests --- coderd/coderd.go | 6 +- coderd/coderdtest/authorize.go | 121 +++++++++++++++++++++++++++- coderd/coderdtest/authorize_test.go | 37 +++++++++ coderd/coderdtest/coderdtest.go | 9 ++- 4 files changed, 162 insertions(+), 11 deletions(-) diff --git a/coderd/coderd.go b/coderd/coderd.go index cebf9c33d8494..20ba3da7f4bc3 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -164,6 +164,9 @@ func New(options *Options) *API { options = &Options{} } + if options.Authorizer == nil { + options.Authorizer = rbac.NewCachingAuthorizer(options.PrometheusRegistry) + } options.Database = dbauthz.New( options.Database, options.Authorizer, @@ -204,9 +207,6 @@ func New(options *Options) *API { if options.PrometheusRegistry == nil { options.PrometheusRegistry = prometheus.NewRegistry() } - if options.Authorizer == nil { - options.Authorizer = rbac.NewCachingAuthorizer(options.PrometheusRegistry) - } if options.TailnetCoordinator == nil { options.TailnetCoordinator = tailnet.NewCoordinator() } diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 41e4c810e7f98..696de675e7d98 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -19,16 +19,92 @@ import ( "github.com/stretchr/testify/require" "golang.org/x/xerrors" - "github.com/coder/coder/cryptorand" - "github.com/coder/coder/coderd" + "github.com/coder/coder/coderd/database/dbauthz" "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/coderd/rbac/regosql" "github.com/coder/coder/codersdk" + "github.com/coder/coder/cryptorand" "github.com/coder/coder/provisioner/echo" "github.com/coder/coder/provisionersdk/proto" ) +type CoderSDKObject interface { + codersdk.User +} + +func RBACObject[C CoderSDKObject](o C) rbac.Object { + switch ro := any(o).(type) { + case codersdk.User: + return rbac.ResourceUser.WithID(ro.ID) + default: + panic("unknown object type") + } +} + +// RBACAsserter is a helper for asserting that the correct RBAC checks are +// performed. This struct is tied to a given user, and only authorizes calls +// for this user are checked. +type RBACAsserter struct { + Subject rbac.Subject + + Recorder *RecordingAuthorizer +} + +func (a RBACAsserter) AllCalls() []rbac.AuthCall { + return a.Recorder.AllCalls(&a.Subject) +} + +// AssertChecked will assert a given rbac check was performed. It does not care +// about order of checks, or any other checks. This is useful when you do not +// care about asserting every check that was performed. +func (a RBACAsserter) AssertChecked(t *testing.T, action rbac.Action, objects ...rbac.Object) { + pairs := make([]ActionObjectPair, 0, len(objects)) + for _, obj := range objects { + pairs = append(pairs, a.Recorder.Pair(action, obj)) + } + a.Recorder.AssertOutOfOrder(t, a.Subject, pairs...) +} + +// AssertInOrder must be called in the correct order of authz checks. If the objects +// or actions are not in the correct order, the test will fail. +func (a RBACAsserter) AssertInOrder(t *testing.T, action rbac.Action, objects ...rbac.Object) { + pairs := make([]ActionObjectPair, 0, len(objects)) + for _, obj := range objects { + pairs = append(pairs, a.Recorder.Pair(action, obj)) + } + a.Recorder.AssertActor(t, a.Subject, pairs...) +} + +func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsserter { + recorder, ok := api.Authorizer.(*RecordingAuthorizer) + if !ok { + t.Fatal("expected RecordingAuthorizer") + } + + // We use the database directly to not cause additional auth checks on behalf + // of the user. This does add authz checks on behalf of the system user, but + // it is hard to avoid that. + ctx := dbauthz.AsSystemRestricted(context.Background()) + token := client.SessionToken() + parts := strings.Split(token, "-") + key, err := api.Database.GetAPIKeyByID(ctx, parts[0]) + require.NoError(t, err, "fetch client api key") + + roles, err := api.Database.GetAuthorizationUserRoles(ctx, key.UserID) + require.NoError(t, err, "fetch user roles") + + return RBACAsserter{ + Subject: rbac.Subject{ + ID: key.UserID.String(), + Roles: rbac.RoleNames(roles.Roles), + Groups: roles.Groups, + Scope: rbac.ScopeName(key.Scope), + }, + Recorder: recorder, + } +} + func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) { // Some quick reused objects workspaceRBACObj := rbac.ResourceWorkspace.WithID(a.Workspace.ID).InOrg(a.Organization.ID).WithOwner(a.Workspace.OwnerID.String()) @@ -598,11 +674,48 @@ func (r *RecordingAuthorizer) AllAsserted() error { return nil } +// AllCalls is useful for debugging. +func (r *RecordingAuthorizer) AllCalls(actor *rbac.Subject) []rbac.AuthCall { + r.RLock() + defer r.RUnlock() + + called := make([]rbac.AuthCall, 0, len(r.Called)) + for _, c := range r.Called { + if actor != nil && !c.Actor.Equal(*actor) { + continue + } + called = append(called, c.AuthCall) + } + return called +} + +// AssertOutOfOrder asserts that the given actor performed the given action +// on the given objects. It does not care about the order of the calls. +// When marking authz calls as asserted, it will mark the first matching +// calls first. +func (r *RecordingAuthorizer) AssertOutOfOrder(t *testing.T, actor rbac.Subject, did ...ActionObjectPair) { + r.Lock() + defer r.Unlock() + + for _, do := range did { + found := false + // Find the first non-asserted call that matches the actor, action, and object. + for i, call := range r.Called { + if !call.asserted && call.Actor.Equal(actor) && call.Action == do.Action && call.Object.Equal(do.Object) { + r.Called[i].asserted = true + found = true + break + } + } + require.True(t, found, "assertion missing: %s %s %s", actor, do.Action, do.Object) + } +} + // AssertActor asserts in order. If the order of authz calls does not match, // this will fail. func (r *RecordingAuthorizer) AssertActor(t *testing.T, actor rbac.Subject, did ...ActionObjectPair) { - r.RLock() - defer r.RUnlock() + r.Lock() + defer r.Unlock() ptr := 0 for i, call := range r.Called { if ptr == len(did) { diff --git a/coderd/coderdtest/authorize_test.go b/coderd/coderdtest/authorize_test.go index 8ef2ef05d9b7b..cbe4d9d6c6eae 100644 --- a/coderd/coderdtest/authorize_test.go +++ b/coderd/coderdtest/authorize_test.go @@ -2,6 +2,7 @@ package coderdtest_test import ( "context" + "math/rand" "os" "strings" "testing" @@ -81,6 +82,42 @@ func TestAuthzRecorder(t *testing.T) { rec.AssertActor(t, a, aPairs...) require.NoError(t, rec.AllAsserted(), "all assertions should have been made") }) + + t.Run("AuthorizeOutOfOrder", func(t *testing.T) { + t.Parallel() + + rec := &coderdtest.RecordingAuthorizer{ + Wrapped: &coderdtest.FakeAuthorizer{}, + } + sub := coderdtest.RandomRBACSubject() + pairs := fuzzAuthz(t, sub, rec, 10) + rand.Shuffle(len(pairs), func(i, j int) { + pairs[i], pairs[j] = pairs[j], pairs[i] + }) + + rec.AssertOutOfOrder(t, sub, pairs...) + require.NoError(t, rec.AllAsserted(), "all assertions should have been made") + }) + + t.Run("AllCalls", func(t *testing.T) { + t.Parallel() + + rec := &coderdtest.RecordingAuthorizer{ + Wrapped: &coderdtest.FakeAuthorizer{}, + } + sub := coderdtest.RandomRBACSubject() + calls := rec.AllCalls(&sub) + pairs := make([]coderdtest.ActionObjectPair, 0, len(calls)) + for _, call := range calls { + pairs = append(pairs, coderdtest.ActionObjectPair{ + Action: call.Action, + Object: call.Object, + }) + } + + rec.AssertActor(t, sub, pairs...) + require.NoError(t, rec.AllAsserted(), "all assertions should have been made") + }) } // fuzzAuthzPrep has same action and object types for all calls. diff --git a/coderd/coderdtest/coderdtest.go b/coderd/coderdtest/coderdtest.go index 274d044175179..3500cb31388d6 100644 --- a/coderd/coderdtest/coderdtest.go +++ b/coderd/coderdtest/coderdtest.go @@ -180,10 +180,6 @@ func NewOptions(t *testing.T, options *Options) (func(http.Handler), context.Can close(options.AutobuildStats) }) } - if options.Database == nil { - options.Database, options.Pubsub = dbtestutil.NewDB(t) - } - options.Database = dbauthz.New(options.Database, options.Authorizer, slogtest.Make(t, nil).Leveled(slog.LevelDebug)) if options.Authorizer == nil { options.Authorizer = &RecordingAuthorizer{ @@ -191,6 +187,11 @@ func NewOptions(t *testing.T, options *Options) (func(http.Handler), context.Can } } + if options.Database == nil { + options.Database, options.Pubsub = dbtestutil.NewDB(t) + options.Database = dbauthz.New(options.Database, options.Authorizer, slogtest.Make(t, nil).Leveled(slog.LevelDebug)) + } + if options.DeploymentValues == nil { options.DeploymentValues = DeploymentValues(t) } From c555c5750bcd5a4a3b3e67e1090bc105474d8152 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 10:14:52 -0500 Subject: [PATCH 03/29] Remove AuthorizeAllEndpoints --- coderd/coderdtest/authorize.go | 529 ------------------ coderd/coderdtest/authorize_test.go | 20 - .../coderdenttest/coderdenttest_test.go | 106 ---- 3 files changed, 655 deletions(-) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 696de675e7d98..de8b579416b2c 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -1,18 +1,11 @@ package coderdtest import ( - "bytes" "context" - "fmt" - "io" - "net/http" - "strconv" "strings" "sync" "testing" - "time" - "github.com/go-chi/chi/v5" "github.com/google/uuid" "github.com/moby/moby/pkg/namesgenerator" "github.com/stretchr/testify/assert" @@ -25,8 +18,6 @@ import ( "github.com/coder/coder/coderd/rbac/regosql" "github.com/coder/coder/codersdk" "github.com/coder/coder/cryptorand" - "github.com/coder/coder/provisioner/echo" - "github.com/coder/coder/provisionersdk/proto" ) type CoderSDKObject interface { @@ -105,526 +96,6 @@ func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsse } } -func AGPLRoutes(a *AuthTester) (map[string]string, map[string]RouteCheck) { - // Some quick reused objects - workspaceRBACObj := rbac.ResourceWorkspace.WithID(a.Workspace.ID).InOrg(a.Organization.ID).WithOwner(a.Workspace.OwnerID.String()) - workspaceExecObj := rbac.ResourceWorkspaceExecution.WithID(a.Workspace.ID).InOrg(a.Organization.ID).WithOwner(a.Workspace.OwnerID.String()) - applicationConnectObj := rbac.ResourceWorkspaceApplicationConnect.WithID(a.Workspace.ID).InOrg(a.Organization.ID).WithOwner(a.Workspace.OwnerID.String()) - templateObj := rbac.ResourceTemplate.WithID(a.Template.ID).InOrg(a.Template.OrganizationID) - - // skipRoutes allows skipping routes from being checked. - skipRoutes := map[string]string{ - "POST:/api/v2/users/logout": "Logging out deletes the API Key for other routes", - "GET:/derp": "This requires a WebSocket upgrade!", - "GET:/derp/latency-check": "This always returns a 200!", - } - - assertRoute := map[string]RouteCheck{ - // These endpoints do not require auth - "GET:/healthz": {NoAuthorize: true}, - "GET:/api/v2": {NoAuthorize: true}, - "GET:/api/v2/buildinfo": {NoAuthorize: true}, - "GET:/api/v2/experiments": {NoAuthorize: true}, // This route requires AuthN, but not AuthZ. - "GET:/api/v2/updatecheck": {NoAuthorize: true}, - "GET:/api/v2/users/first": {NoAuthorize: true}, - "POST:/api/v2/users/first": {NoAuthorize: true}, - "POST:/api/v2/users/login": {NoAuthorize: true}, - "GET:/api/v2/users/authmethods": {NoAuthorize: true}, - "POST:/api/v2/csp/reports": {NoAuthorize: true}, - "POST:/api/v2/authcheck": {NoAuthorize: true}, - "GET:/api/v2/applications/host": {NoAuthorize: true}, - - // Has it's own auth - "GET:/api/v2/users/oauth2/github/callback": {NoAuthorize: true}, - "GET:/api/v2/users/oidc/callback": {NoAuthorize: true}, - - // All workspaceagents endpoints do not use rbac - "POST:/api/v2/workspaceagents/aws-instance-identity": {NoAuthorize: true}, - "POST:/api/v2/workspaceagents/azure-instance-identity": {NoAuthorize: true}, - "POST:/api/v2/workspaceagents/google-instance-identity": {NoAuthorize: true}, - "GET:/api/v2/workspaceagents/me/gitauth": {NoAuthorize: true}, - "GET:/api/v2/workspaceagents/me/gitsshkey": {NoAuthorize: true}, - "GET:/api/v2/workspaceagents/me/metadata": {NoAuthorize: true}, - "GET:/api/v2/workspaceagents/me/coordinate": {NoAuthorize: true}, - "POST:/api/v2/workspaceagents/me/startup": {NoAuthorize: true}, - "POST:/api/v2/workspaceagents/me/app-health": {NoAuthorize: true}, - "POST:/api/v2/workspaceagents/me/report-stats": {NoAuthorize: true}, - "POST:/api/v2/workspaceagents/me/report-lifecycle": {NoAuthorize: true}, - - // These endpoints have more assertions. This is good, add more endpoints to assert if you can! - "GET:/api/v2/organizations/{organization}": {AssertObject: rbac.ResourceOrganization.WithID(a.Admin.OrganizationID).InOrg(a.Admin.OrganizationID)}, - "GET:/api/v2/users/{user}/organizations": {StatusCode: http.StatusOK, AssertObject: rbac.ResourceOrganization}, - "GET:/api/v2/users/{user}/workspace/{workspacename}": { - AssertObject: rbac.ResourceWorkspace, - AssertAction: rbac.ActionRead, - }, - "GET:/api/v2/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { - AssertObject: rbac.ResourceWorkspace, - AssertAction: rbac.ActionRead, - }, - "GET:/api/v2/users/{user}/keys/tokens": { - AssertObject: rbac.ResourceAPIKey, - AssertAction: rbac.ActionRead, - StatusCode: http.StatusOK, - }, - "GET:/api/v2/users/{user}/keys/{keyid}": { - AssertObject: rbac.ResourceAPIKey, - AssertAction: rbac.ActionRead, - }, - "GET:/api/v2/users/{user}/keys/tokens/{keyname}": { - AssertObject: rbac.ResourceAPIKey, - AssertAction: rbac.ActionRead, - }, - "GET:/api/v2/users/{user}/keys/tokens/tokenconfig": {NoAuthorize: true}, - "GET:/api/v2/workspacebuilds/{workspacebuild}": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspacebuilds/{workspacebuild}/logs": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspaces/{workspace}/builds": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspaces/{workspace}": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "PUT:/api/v2/workspaces/{workspace}/autostart": { - AssertAction: rbac.ActionUpdate, - AssertObject: workspaceRBACObj, - }, - "PUT:/api/v2/workspaces/{workspace}/ttl": { - AssertAction: rbac.ActionUpdate, - AssertObject: workspaceRBACObj, - }, - "PATCH:/api/v2/workspacebuilds/{workspacebuild}/cancel": { - AssertAction: rbac.ActionUpdate, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspacebuilds/{workspacebuild}/resources": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspacebuilds/{workspacebuild}/state": { - AssertAction: rbac.ActionUpdate, - AssertObject: templateObj, - }, - "GET:/api/v2/workspaceagents/{workspaceagent}": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspaceagents/{workspaceagent}/pty": { - AssertAction: rbac.ActionCreate, - AssertObject: workspaceExecObj, - }, - "GET:/api/v2/workspaceagents/{workspaceagent}/coordinate": { - AssertAction: rbac.ActionCreate, - AssertObject: workspaceExecObj, - }, - "POST:/api/v2/organizations/{organization}/templates": { - AssertAction: rbac.ActionCreate, - AssertObject: rbac.ResourceTemplate.InOrg(a.Organization.ID), - }, - "DELETE:/api/v2/templates/{template}": { - AssertAction: rbac.ActionDelete, - AssertObject: templateObj, - }, - "GET:/api/v2/templates/{template}": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "POST:/api/v2/files": {AssertAction: rbac.ActionCreate, AssertObject: rbac.ResourceFile}, - "GET:/api/v2/files/{fileID}": { - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceFile.WithOwner(a.Admin.UserID.String()), - }, - "GET:/api/v2/templates/{template}/versions": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "PATCH:/api/v2/templates/{template}/versions": { - AssertAction: rbac.ActionUpdate, - AssertObject: templateObj, - }, - "GET:/api/v2/templates/{template}/versions/{templateversionname}": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "PATCH:/api/v2/templateversions/{templateversion}/cancel": { - AssertAction: rbac.ActionUpdate, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/logs": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/parameters": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/rich-parameters": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/resources": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/schema": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "POST:/api/v2/templateversions/{templateversion}/dry-run": { - // The first check is to read the template - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/dry-run/{jobID}": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/dry-run/{jobID}/resources": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/templateversions/{templateversion}/dry-run/{jobID}/logs": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "PATCH:/api/v2/templateversions/{templateversion}/dry-run/{jobID}/cancel": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "POST:/api/v2/parameters/{scope}/{id}": { - AssertAction: rbac.ActionUpdate, - AssertObject: rbac.ResourceTemplate, - }, - "GET:/api/v2/parameters/{scope}/{id}": { - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceTemplate, - }, - "DELETE:/api/v2/parameters/{scope}/{id}/{name}": { - AssertAction: rbac.ActionUpdate, - AssertObject: rbac.ResourceTemplate, - }, - "GET:/api/v2/organizations/{organization}/templates/{templatename}": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "GET:/api/v2/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": { - AssertAction: rbac.ActionRead, - AssertObject: templateObj, - }, - "POST:/api/v2/organizations/{organization}/members/{user}/workspaces": { - AssertAction: rbac.ActionCreate, - // No ID when creating - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/workspaces/{workspace}/watch": { - AssertAction: rbac.ActionRead, - AssertObject: workspaceRBACObj, - }, - "GET:/api/v2/users": {StatusCode: http.StatusOK, AssertObject: rbac.ResourceUser}, - "GET:/api/v2/applications/auth-redirect": {AssertAction: rbac.ActionCreate, AssertObject: rbac.ResourceAPIKey}, - - // These endpoints need payloads to get to the auth part. Payloads will be required - "PUT:/api/v2/users/{user}/roles": {StatusCode: http.StatusBadRequest, NoAuthorize: true}, - "PUT:/api/v2/organizations/{organization}/members/{user}/roles": {NoAuthorize: true}, - "POST:/api/v2/workspaces/{workspace}/builds": {StatusCode: http.StatusBadRequest, NoAuthorize: true}, - "POST:/api/v2/organizations/{organization}/templateversions": {StatusCode: http.StatusBadRequest, NoAuthorize: true}, - - // For any route using SQL filters, we do not check authorization. - // This is because the in memory fake does not use SQL. - "GET:/api/v2/workspaces/": { - StatusCode: http.StatusOK, - NoAuthorize: true, - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceWorkspace, - }, - "GET:/api/v2/organizations/{organization}/templates": { - StatusCode: http.StatusOK, - NoAuthorize: true, - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceTemplate, - }, - - "GET:/api/v2/debug/coordinator": { - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceDebugInfo, - }, - } - - // Routes like proxy routes support all HTTP methods. A helper func to expand - // 1 url to all http methods. - assertAllHTTPMethods := func(url string, check RouteCheck) { - methods := []string{ - http.MethodGet, http.MethodHead, http.MethodPost, - http.MethodPut, http.MethodPatch, http.MethodDelete, - http.MethodConnect, http.MethodOptions, http.MethodTrace, - } - - for _, method := range methods { - route := method + ":" + url - assertRoute[route] = check - } - } - - assertAllHTTPMethods("/%40{user}/{workspace_and_agent}/apps/{workspaceapp}/*", RouteCheck{ - AssertAction: rbac.ActionCreate, - AssertObject: applicationConnectObj, - }) - assertAllHTTPMethods("/@{user}/{workspace_and_agent}/apps/{workspaceapp}/*", RouteCheck{ - AssertAction: rbac.ActionCreate, - AssertObject: applicationConnectObj, - }) - - return skipRoutes, assertRoute -} - -type RouteCheck struct { - NoAuthorize bool - AssertAction rbac.Action - AssertObject rbac.Object - StatusCode int -} - -type AuthTester struct { - t *testing.T - api *coderd.API - authorizer *RecordingAuthorizer - - Client *codersdk.Client - Workspace codersdk.Workspace - Organization codersdk.Organization - Admin codersdk.CreateFirstUserResponse - Template codersdk.Template - Version codersdk.TemplateVersion - WorkspaceResource codersdk.WorkspaceResource - File codersdk.UploadResponse - TemplateVersionDryRun codersdk.ProvisionerJob - TemplateParam codersdk.Parameter - URLParams map[string]string -} - -func NewAuthTester(ctx context.Context, t *testing.T, client *codersdk.Client, api *coderd.API, admin codersdk.CreateFirstUserResponse) *AuthTester { - authorizer, ok := api.Authorizer.(*RecordingAuthorizer) - if !ok { - t.Fail() - } - _, err := client.CreateToken(ctx, admin.UserID.String(), codersdk.CreateTokenRequest{ - Lifetime: time.Hour, - Scope: codersdk.APIKeyScopeAll, - TokenName: namesgenerator.GetRandomName(1), - }) - require.NoError(t, err, "create token") - - apiKeys, err := client.Tokens(ctx, admin.UserID.String(), codersdk.TokensFilter{ - IncludeAll: true, - }) - require.NoError(t, err, "get tokens") - apiKey := apiKeys[0] - - organization, err := client.Organization(ctx, admin.OrganizationID) - require.NoError(t, err, "fetch org") - - // Setup some data in the database. - version := CreateTemplateVersion(t, client, admin.OrganizationID, &echo.Responses{ - Parse: echo.ParseComplete, - ProvisionApply: []*proto.Provision_Response{{ - Type: &proto.Provision_Response_Complete{ - Complete: &proto.Provision_Complete{ - // Return a workspace resource - Resources: []*proto.Resource{{ - Name: "some", - Type: "example", - Agents: []*proto.Agent{{ - Name: "agent", - Id: "something", - Auth: &proto.Agent_Token{}, - Apps: []*proto.App{{ - Slug: "testapp", - DisplayName: "testapp", - Url: "http://localhost:3000", - }}, - }}, - }}, - }, - }, - }}, - }) - AwaitTemplateVersionJob(t, client, version.ID) - template := CreateTemplate(t, client, admin.OrganizationID, version.ID) - workspace := CreateWorkspace(t, client, admin.OrganizationID, template.ID) - AwaitWorkspaceBuildJob(t, client, workspace.LatestBuild.ID) - file, err := client.Upload(ctx, codersdk.ContentTypeTar, bytes.NewReader(make([]byte, 1024))) - require.NoError(t, err, "upload file") - workspace, err = client.Workspace(ctx, workspace.ID) - require.NoError(t, err, "workspace resources") - templateVersionDryRun, err := client.CreateTemplateVersionDryRun(ctx, version.ID, codersdk.CreateTemplateVersionDryRunRequest{ - ParameterValues: []codersdk.CreateParameterRequest{}, - }) - require.NoError(t, err, "template version dry-run") - - templateParam, err := client.CreateParameter(ctx, codersdk.ParameterTemplate, template.ID, codersdk.CreateParameterRequest{ - Name: "test-param", - SourceValue: "hello world", - SourceScheme: codersdk.ParameterSourceSchemeData, - DestinationScheme: codersdk.ParameterDestinationSchemeProvisionerVariable, - }) - require.NoError(t, err, "create template param") - urlParameters := map[string]string{ - "{organization}": admin.OrganizationID.String(), - "{user}": admin.UserID.String(), - "{organizationname}": organization.Name, - "{workspace}": workspace.ID.String(), - "{workspacebuild}": workspace.LatestBuild.ID.String(), - "{workspacename}": workspace.Name, - "{workspaceagent}": workspace.LatestBuild.Resources[0].Agents[0].ID.String(), - "{buildnumber}": strconv.FormatInt(int64(workspace.LatestBuild.BuildNumber), 10), - "{template}": template.ID.String(), - "{fileID}": file.ID.String(), - "{workspaceresource}": workspace.LatestBuild.Resources[0].ID.String(), - "{workspaceapp}": workspace.LatestBuild.Resources[0].Agents[0].Apps[0].Slug, - "{templateversion}": version.ID.String(), - "{jobID}": templateVersionDryRun.ID.String(), - "{templatename}": template.Name, - "{workspace_and_agent}": workspace.Name + "." + workspace.LatestBuild.Resources[0].Agents[0].Name, - "{keyid}": apiKey.ID, - "{keyname}": apiKey.TokenName, - // Only checking template scoped params here - "parameters/{scope}/{id}": fmt.Sprintf("parameters/%s/%s", - string(templateParam.Scope), templateParam.ScopeID.String()), - } - - return &AuthTester{ - t: t, - api: api, - authorizer: authorizer, - Client: client, - Workspace: workspace, - Organization: organization, - Admin: admin, - Template: template, - Version: version, - WorkspaceResource: workspace.LatestBuild.Resources[0], - File: file, - TemplateVersionDryRun: templateVersionDryRun, - TemplateParam: templateParam, - URLParams: urlParameters, - } -} - -func (a *AuthTester) Test(ctx context.Context, assertRoute map[string]RouteCheck, skipRoutes map[string]string) { - // Always fail auth from this point forward - a.authorizer.Wrapped = &FakeAuthorizer{ - AlwaysReturn: rbac.ForbiddenWithInternal(xerrors.New("fake implementation"), rbac.Subject{}, "", rbac.Object{}, nil), - } - - routeMissing := make(map[string]bool) - for k, v := range assertRoute { - noTrailSlash := strings.TrimRight(k, "/") - if _, ok := assertRoute[noTrailSlash]; ok && noTrailSlash != k { - a.t.Errorf("route %q & %q is declared twice", noTrailSlash, k) - a.t.FailNow() - } - assertRoute[noTrailSlash] = v - routeMissing[noTrailSlash] = true - } - - for k, v := range skipRoutes { - noTrailSlash := strings.TrimRight(k, "/") - if _, ok := skipRoutes[noTrailSlash]; ok && noTrailSlash != k { - a.t.Errorf("route %q & %q is declared twice", noTrailSlash, k) - a.t.FailNow() - } - skipRoutes[noTrailSlash] = v - } - - err := chi.Walk( - a.api.RootHandler, - func( - method string, - route string, - handler http.Handler, - middlewares ...func(http.Handler) http.Handler, - ) error { - // work around chi's bugged handling of /*/*/ which can occur if we - // r.Mount("/", someHandler()) in our tree - for strings.Contains(route, "/*/") { - route = strings.Replace(route, "/*/", "/", -1) - } - name := method + ":" + route - if _, ok := skipRoutes[strings.TrimRight(name, "/")]; ok { - return nil - } - a.t.Run(name, func(t *testing.T) { - a.authorizer.Reset() - routeKey := strings.TrimRight(name, "/") - - routeAssertions, ok := assertRoute[routeKey] - if !ok { - // By default, all omitted routes check for just "authorize" called - routeAssertions = RouteCheck{} - } - delete(routeMissing, routeKey) - - // Replace all url params with known values - for k, v := range a.URLParams { - route = strings.ReplaceAll(route, k, v) - } - - resp, err := a.Client.Request(ctx, method, route, nil) - require.NoError(t, err, "do req") - body, _ := io.ReadAll(resp.Body) - t.Logf("Response Body: %q", string(body)) - _ = resp.Body.Close() - - if !routeAssertions.NoAuthorize { - assert.NotNil(t, a.authorizer.Called, "authorizer expected") - if routeAssertions.StatusCode != 0 { - assert.Equal(t, routeAssertions.StatusCode, resp.StatusCode, "expect unauthorized") - } else { - // It's either a 404 or 403. - if resp.StatusCode != http.StatusNotFound { - assert.Equal(t, http.StatusForbidden, resp.StatusCode, "expect unauthorized") - } - } - if a.authorizer.lastCall() != nil { - last := a.authorizer.lastCall() - if routeAssertions.AssertAction != "" { - assert.Equal(t, routeAssertions.AssertAction, last.Action, "resource action") - } - if routeAssertions.AssertObject.Type != "" { - assert.Equal(t, routeAssertions.AssertObject.Type, last.Object.Type, "resource type") - } - if routeAssertions.AssertObject.Owner != "" { - assert.Equal(t, routeAssertions.AssertObject.Owner, last.Object.Owner, "resource owner") - } - if routeAssertions.AssertObject.OrgID != "" { - assert.Equal(t, routeAssertions.AssertObject.OrgID, last.Object.OrgID, "resource org") - } - } - } else { - assert.Nil(t, a.authorizer.Called, "authorize not expected") - } - }) - return nil - }) - require.NoError(a.t, err) - require.Len(a.t, routeMissing, 0, "didn't walk some asserted routes: %v", routeMissing) -} - type authCall struct { rbac.AuthCall diff --git a/coderd/coderdtest/authorize_test.go b/coderd/coderdtest/authorize_test.go index cbe4d9d6c6eae..67bcf482def75 100644 --- a/coderd/coderdtest/authorize_test.go +++ b/coderd/coderdtest/authorize_test.go @@ -3,34 +3,14 @@ package coderdtest_test import ( "context" "math/rand" - "os" - "strings" "testing" "github.com/stretchr/testify/require" "github.com/coder/coder/coderd/coderdtest" "github.com/coder/coder/coderd/rbac" - "github.com/coder/coder/codersdk" ) -func TestAuthorizeAllEndpoints(t *testing.T) { - if strings.Contains(os.Getenv("CODER_EXPERIMENTS_TEST"), string(codersdk.ExperimentAuthzQuerier)) { - t.Skip("Skipping TestAuthorizeAllEndpoints for authz_querier experiment") - } - t.Parallel() - client, _, api := coderdtest.NewWithAPI(t, &coderdtest.Options{ - // Required for any subdomain-based proxy tests to pass. - AppHostname: "*.test.coder.com", - Authorizer: &coderdtest.RecordingAuthorizer{Wrapped: &coderdtest.FakeAuthorizer{}}, - IncludeProvisionerDaemon: true, - }) - admin := coderdtest.CreateFirstUser(t, client) - a := coderdtest.NewAuthTester(context.Background(), t, client, api, admin) - skipRoute, assertRoute := coderdtest.AGPLRoutes(a) - a.Test(context.Background(), assertRoute, skipRoute) -} - func TestAuthzRecorder(t *testing.T) { t.Parallel() diff --git a/enterprise/coderd/coderdenttest/coderdenttest_test.go b/enterprise/coderd/coderdenttest/coderdenttest_test.go index aa32c582e67f9..04d6dab6e96a5 100644 --- a/enterprise/coderd/coderdenttest/coderdenttest_test.go +++ b/enterprise/coderd/coderdenttest/coderdenttest_test.go @@ -1,118 +1,12 @@ package coderdenttest_test import ( - "context" - "fmt" - "net/http" - "os" - "strings" "testing" - "github.com/stretchr/testify/require" - - "github.com/coder/coder/coderd/coderdtest" - "github.com/coder/coder/coderd/rbac" - "github.com/coder/coder/codersdk" "github.com/coder/coder/enterprise/coderd/coderdenttest" - "github.com/coder/coder/enterprise/coderd/license" - "github.com/coder/coder/testutil" ) func TestNew(t *testing.T) { t.Parallel() _ = coderdenttest.New(t, nil) } - -func TestAuthorizeAllEndpoints(t *testing.T) { - if strings.Contains(os.Getenv("CODER_EXPERIMENTS_TEST"), string(codersdk.ExperimentAuthzQuerier)) { - t.Skip("Skipping TestAuthorizeAllEndpoints for authz_querier experiment") - } - t.Parallel() - client, _, api := coderdenttest.NewWithAPI(t, &coderdenttest.Options{ - Options: &coderdtest.Options{ - // Required for any subdomain-based proxy tests to pass. - AppHostname: "*.test.coder.com", - Authorizer: &coderdtest.RecordingAuthorizer{Wrapped: &coderdtest.FakeAuthorizer{}}, - IncludeProvisionerDaemon: true, - }, - }) - ctx, _ := testutil.Context(t) - admin := coderdtest.CreateFirstUser(t, client) - lic := coderdenttest.AddLicense(t, client, coderdenttest.LicenseOptions{ - Features: license.Features{ - codersdk.FeatureTemplateRBAC: 1, - codersdk.FeatureExternalProvisionerDaemons: 1, - }, - }) - group, err := client.CreateGroup(ctx, admin.OrganizationID, codersdk.CreateGroupRequest{ - Name: "testgroup", - }) - require.NoError(t, err) - - groupObj := rbac.ResourceGroup.WithID(group.ID).InOrg(admin.OrganizationID) - a := coderdtest.NewAuthTester(ctx, t, client, api.AGPL, admin) - a.URLParams["licenses/{id}"] = fmt.Sprintf("licenses/%d", lic.ID) - a.URLParams["groups/{group}"] = fmt.Sprintf("groups/%s", group.ID.String()) - a.URLParams["{groupName}"] = group.Name - - skipRoutes, assertRoute := coderdtest.AGPLRoutes(a) - skipRoutes["GET:/api/v2/organizations/{organization}/provisionerdaemons/serve"] = "This route checks for RBAC dependent on input parameters!" - skipRoutes["GET:/api/v2/appearance/"] = "This route is available to all users" - - assertRoute["GET:/api/v2/entitlements"] = coderdtest.RouteCheck{ - NoAuthorize: true, - } - assertRoute["POST:/api/v2/licenses"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionCreate, - AssertObject: rbac.ResourceLicense, - } - assertRoute["GET:/api/v2/licenses"] = coderdtest.RouteCheck{ - StatusCode: http.StatusOK, - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceLicense, - } - assertRoute["GET:/api/v2/replicas"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceReplicas, - } - assertRoute["DELETE:/api/v2/licenses/{id}"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionDelete, - AssertObject: rbac.ResourceLicense, - } - assertRoute["GET:/api/v2/templates/{template}/acl"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceTemplate, - } - assertRoute["PATCH:/api/v2/templates/{template}/acl"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionCreate, - AssertObject: rbac.ResourceTemplate, - } - assertRoute["GET:/api/v2/organizations/{organization}/groups"] = coderdtest.RouteCheck{ - StatusCode: http.StatusOK, - AssertAction: rbac.ActionRead, - AssertObject: groupObj, - } - assertRoute["GET:/api/v2/organizations/{organization}/groups/{groupName}"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionRead, - AssertObject: groupObj, - } - assertRoute["GET:/api/v2/organizations/{organization}/provisionerdaemons"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionRead, - AssertObject: rbac.ResourceProvisionerDaemon, - StatusCode: http.StatusOK, - } - assertRoute["GET:/api/v2/groups/{group}"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionRead, - AssertObject: groupObj, - } - assertRoute["PATCH:/api/v2/groups/{group}"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionUpdate, - AssertObject: groupObj, - } - assertRoute["DELETE:/api/v2/groups/{group}"] = coderdtest.RouteCheck{ - AssertAction: rbac.ActionDelete, - AssertObject: groupObj, - } - - a.Test(context.Background(), assertRoute, skipRoutes) -} From c6210c49114202c08b39cf868fef9b73dc64e2a2 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 10:45:32 -0500 Subject: [PATCH 04/29] Remove some duplicate rbac checks --- coderd/apikey.go | 26 ------------ coderd/audit.go | 8 ---- coderd/coderdtest/authorize.go | 40 ++++++++++++++---- coderd/files.go | 13 ------ coderd/gitsshkey.go | 11 ----- coderd/members.go | 24 ----------- coderd/organizations.go | 11 ----- coderd/parameters.go | 75 ---------------------------------- 8 files changed, 31 insertions(+), 177 deletions(-) diff --git a/coderd/apikey.go b/coderd/apikey.go index 19867afb77a95..4b657cd28016b 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -43,11 +43,6 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAPIKey.WithOwner(user.ID.String())) { - httpapi.ResourceNotFound(rw) - return - } - var createToken codersdk.CreateTokenRequest if !httpapi.Read(ctx, rw, r, &createToken) { return @@ -122,11 +117,6 @@ func (api *API) postAPIKey(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAPIKey.WithOwner(user.ID.String())) { - httpapi.ResourceNotFound(rw) - return - } - lifeTime := time.Hour * 24 * 7 cookie, _, err := api.createAPIKey(ctx, createAPIKeyParams{ UserID: user.ID, @@ -178,11 +168,6 @@ func (api *API) apiKeyByID(rw http.ResponseWriter, r *http.Request) { return } - if !api.Authorize(r, rbac.ActionRead, key) { - httpapi.ResourceNotFound(rw) - return - } - httpapi.Write(ctx, rw, http.StatusOK, convertAPIKey(key)) } @@ -218,11 +203,6 @@ func (api *API) apiKeyByName(rw http.ResponseWriter, r *http.Request) { return } - if !api.Authorize(r, rbac.ActionRead, token) { - httpapi.ResourceNotFound(rw) - return - } - httpapi.Write(ctx, rw, http.StatusOK, convertAPIKey(token)) } @@ -315,15 +295,9 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) { func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() - user = httpmw.UserParam(r) keyID = chi.URLParam(r, "keyid") ) - if !api.Authorize(r, rbac.ActionDelete, rbac.ResourceAPIKey.WithIDString(keyID).WithOwner(user.ID.String())) { - httpapi.ResourceNotFound(rw) - return - } - err := api.Database.DeleteAPIKeyByID(ctx, keyID) if errors.Is(err, sql.ErrNoRows) { httpapi.ResourceNotFound(rw) diff --git a/coderd/audit.go b/coderd/audit.go index 493b5bec795f4..834756a1a4d9f 100644 --- a/coderd/audit.go +++ b/coderd/audit.go @@ -37,10 +37,6 @@ import ( // @Router /audit [get] func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - if !api.Authorize(r, rbac.ActionRead, rbac.ResourceAuditLog) { - httpapi.Forbidden(rw) - return - } page, ok := parsePagination(rw, r) if !ok { @@ -90,10 +86,6 @@ func (api *API) auditLogs(rw http.ResponseWriter, r *http.Request) { // @Router /audit/testgenerate [post] func (api *API) generateFakeAuditLog(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceAuditLog) { - httpapi.Forbidden(rw) - return - } key := httpmw.APIKey(r) user, err := api.Database.GetUserByID(ctx, key.UserID) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index de8b579416b2c..e8a85ab52cc12 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -2,6 +2,8 @@ package coderdtest import ( "context" + "fmt" + "runtime" "strings" "sync" "testing" @@ -42,7 +44,7 @@ type RBACAsserter struct { Recorder *RecordingAuthorizer } -func (a RBACAsserter) AllCalls() []rbac.AuthCall { +func (a RBACAsserter) AllCalls() []AuthCall { return a.Recorder.AllCalls(&a.Subject) } @@ -67,6 +69,12 @@ func (a RBACAsserter) AssertInOrder(t *testing.T, action rbac.Action, objects .. a.Recorder.AssertActor(t, a.Subject, pairs...) } +// Reset will clear all previously recorded authz calls. +func (a RBACAsserter) Reset() RBACAsserter { + a.Recorder.Reset() + return a +} + func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsserter { recorder, ok := api.Authorizer.(*RecordingAuthorizer) if !ok { @@ -96,10 +104,11 @@ func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsse } } -type authCall struct { +type AuthCall struct { rbac.AuthCall asserted bool + caller string } var _ rbac.Authorizer = (*RecordingAuthorizer)(nil) @@ -108,7 +117,7 @@ var _ rbac.Authorizer = (*RecordingAuthorizer)(nil) // calls made. This is useful for testing as these calls can later be asserted. type RecordingAuthorizer struct { sync.RWMutex - Called []authCall + Called []AuthCall Wrapped rbac.Authorizer } @@ -132,7 +141,7 @@ func (*RecordingAuthorizer) Pair(action rbac.Action, object rbac.Objecter) Actio func (r *RecordingAuthorizer) AllAsserted() error { r.RLock() defer r.RUnlock() - missed := []authCall{} + missed := []AuthCall{} for _, c := range r.Called { if !c.asserted { missed = append(missed, c) @@ -146,16 +155,16 @@ func (r *RecordingAuthorizer) AllAsserted() error { } // AllCalls is useful for debugging. -func (r *RecordingAuthorizer) AllCalls(actor *rbac.Subject) []rbac.AuthCall { +func (r *RecordingAuthorizer) AllCalls(actor *rbac.Subject) []AuthCall { r.RLock() defer r.RUnlock() - called := make([]rbac.AuthCall, 0, len(r.Called)) + called := make([]AuthCall, 0, len(r.Called)) for _, c := range r.Called { if actor != nil && !c.Actor.Equal(*actor) { continue } - called = append(called, c.AuthCall) + called = append(called, c) } return called } @@ -209,12 +218,25 @@ func (r *RecordingAuthorizer) AssertActor(t *testing.T, actor rbac.Subject, did func (r *RecordingAuthorizer) recordAuthorize(subject rbac.Subject, action rbac.Action, object rbac.Object) { r.Lock() defer r.Unlock() - r.Called = append(r.Called, authCall{ + + pc, file, line, ok := runtime.Caller(2) + i := strings.Index(file, "coder") + if i >= 0 { + file = file[i:] + } + caller := fmt.Sprintf("%s:%d", file, line) + if ok { + f := runtime.FuncForPC(pc) + caller += " " + strings.TrimPrefix(f.Name(), "github.com/coder") + } + + r.Called = append(r.Called, AuthCall{ AuthCall: rbac.AuthCall{ Actor: subject, Action: action, Object: object, }, + caller: caller, }) } @@ -254,7 +276,7 @@ func (r *RecordingAuthorizer) Reset() { // lastCall is implemented to support legacy tests. // Deprecated -func (r *RecordingAuthorizer) lastCall() *authCall { +func (r *RecordingAuthorizer) lastCall() *AuthCall { r.RLock() defer r.RUnlock() if len(r.Called) == 0 { diff --git a/coderd/files.go b/coderd/files.go index 91858eb3ca06e..1362bfef7ebde 100644 --- a/coderd/files.go +++ b/coderd/files.go @@ -15,7 +15,6 @@ import ( "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/httpapi" "github.com/coder/coder/coderd/httpmw" - "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/codersdk" ) @@ -37,12 +36,6 @@ const ( func (api *API) postFile(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() apiKey := httpmw.APIKey(r) - // This requires the site wide action to create files. - // Once created, a user can read their own files uploaded - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceFile.WithOwner(apiKey.UserID.String())) { - httpapi.Forbidden(rw) - return - } contentType := r.Header.Get("Content-Type") @@ -145,12 +138,6 @@ func (api *API) fileByID(rw http.ResponseWriter, r *http.Request) { return } - if !api.Authorize(r, rbac.ActionRead, file) { - // Return 404 to not leak the file exists - httpapi.ResourceNotFound(rw) - return - } - rw.Header().Set("Content-Type", file.Mimetype) rw.WriteHeader(http.StatusOK) _, _ = rw.Write(file.Data) diff --git a/coderd/gitsshkey.go b/coderd/gitsshkey.go index 3380382f15afd..096844caa0a28 100644 --- a/coderd/gitsshkey.go +++ b/coderd/gitsshkey.go @@ -8,7 +8,6 @@ import ( "github.com/coder/coder/coderd/gitsshkey" "github.com/coder/coder/coderd/httpapi" "github.com/coder/coder/coderd/httpmw" - "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/codersdk" "github.com/coder/coder/codersdk/agentsdk" ) @@ -35,11 +34,6 @@ func (api *API) regenerateGitSSHKey(rw http.ResponseWriter, r *http.Request) { ) defer commitAudit() - if !api.Authorize(r, rbac.ActionUpdate, user.UserDataRBACObject()) { - httpapi.ResourceNotFound(rw) - return - } - oldKey, err := api.Database.GetGitSSHKey(ctx, user.ID) if err != nil { httpapi.InternalServerError(rw, err) @@ -94,11 +88,6 @@ func (api *API) gitSSHKey(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) - if !api.Authorize(r, rbac.ActionRead, user.UserDataRBACObject()) { - httpapi.ResourceNotFound(rw) - return - } - gitSSHKey, err := api.Database.GetGitSSHKey(ctx, user.ID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ diff --git a/coderd/members.go b/coderd/members.go index c3e4607b0f9e5..1c0ea5fb00584 100644 --- a/coderd/members.go +++ b/coderd/members.go @@ -49,30 +49,6 @@ func (api *API) putMemberRoles(rw http.ResponseWriter, r *http.Request) { return } - // The org-member role is always implied. - impliedTypes := append(params.Roles, rbac.RoleOrgMember(organization.ID)) - added, removed := rbac.ChangeRoleSet(member.Roles, impliedTypes) - - // Assigning a role requires the create permission. - if len(added) > 0 && !api.Authorize(r, rbac.ActionCreate, rbac.ResourceOrgRoleAssignment.InOrg(organization.ID)) { - httpapi.ResourceNotFound(rw) - return - } - - // Removing a role requires the delete permission. - if len(removed) > 0 && !api.Authorize(r, rbac.ActionDelete, rbac.ResourceOrgRoleAssignment.InOrg(organization.ID)) { - httpapi.ResourceNotFound(rw) - return - } - - // Just treat adding & removing as "assigning" for now. - for _, roleName := range append(added, removed...) { - if !rbac.CanAssignRole(actorRoles.Actor.Roles, roleName) { - httpapi.ResourceNotFound(rw) - return - } - } - updatedUser, err := api.updateOrganizationMemberRoles(ctx, database.UpdateMemberRolesParams{ GrantedRoles: params.Roles, UserID: user.ID, diff --git a/coderd/organizations.go b/coderd/organizations.go index 19b57a8958e9e..391442db75730 100644 --- a/coderd/organizations.go +++ b/coderd/organizations.go @@ -28,11 +28,6 @@ func (api *API) organization(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) - if !api.Authorize(r, rbac.ActionRead, organization) { - httpapi.ResourceNotFound(rw) - return - } - httpapi.Write(ctx, rw, http.StatusOK, convertOrganization(organization)) } @@ -48,12 +43,6 @@ func (api *API) organization(rw http.ResponseWriter, r *http.Request) { func (api *API) postOrganizations(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() apiKey := httpmw.APIKey(r) - // Create organization uses the organization resource without an OrgID. - // This means you need the site wide permission to make a new organization. - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceOrganization) { - httpapi.Forbidden(rw) - return - } var req codersdk.CreateOrganizationRequest if !httpapi.Read(ctx, rw, r, &req) { diff --git a/coderd/parameters.go b/coderd/parameters.go index 29adb4bf5e43b..59814ba1bd9c5 100644 --- a/coderd/parameters.go +++ b/coderd/parameters.go @@ -14,7 +14,6 @@ import ( "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/httpapi" "github.com/coder/coder/coderd/parameter" - "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/codersdk" ) @@ -35,14 +34,6 @@ func (api *API) postParameter(rw http.ResponseWriter, r *http.Request) { if !valid { return } - obj, ok := api.parameterRBACResource(rw, r, scope, scopeID) - if !ok { - return - } - if !api.Authorize(r, rbac.ActionUpdate, obj) { - httpapi.ResourceNotFound(rw) - return - } var createRequest codersdk.CreateParameterRequest if !httpapi.Read(ctx, rw, r, &createRequest) { @@ -104,15 +95,6 @@ func (api *API) parameters(rw http.ResponseWriter, r *http.Request) { if !valid { return } - obj, ok := api.parameterRBACResource(rw, r, scope, scopeID) - if !ok { - return - } - - if !api.Authorize(r, rbac.ActionRead, obj) { - httpapi.ResourceNotFound(rw) - return - } parameterValues, err := api.Database.ParameterValues(ctx, database.ParameterValuesParams{ Scopes: []database.ParameterScope{scope}, @@ -152,15 +134,6 @@ func (api *API) deleteParameter(rw http.ResponseWriter, r *http.Request) { if !valid { return } - obj, ok := api.parameterRBACResource(rw, r, scope, scopeID) - if !ok { - return - } - // A deleted param is still updating the underlying resource for the scope. - if !api.Authorize(r, rbac.ActionUpdate, obj) { - httpapi.ResourceNotFound(rw) - return - } name := chi.URLParam(r, "name") parameterValue, err := api.Database.GetParameterValueByScopeAndName(ctx, database.GetParameterValueByScopeAndNameParams{ @@ -236,54 +209,6 @@ func convertParameterValue(parameterValue database.ParameterValue) codersdk.Para } } -// parameterRBACResource returns the RBAC resource a parameter scope and scope -// ID is trying to update. For RBAC purposes, adding a param to a resource -// is equivalent to updating/reading the associated resource. -// This means "parameters" are not a new resource, but an extension of existing -// ones. -func (api *API) parameterRBACResource(rw http.ResponseWriter, r *http.Request, scope database.ParameterScope, scopeID uuid.UUID) (rbac.Objecter, bool) { - ctx := r.Context() - var resource rbac.Objecter - var err error - switch scope { - case database.ParameterScopeWorkspace: - resource, err = api.Database.GetWorkspaceByID(ctx, scopeID) - case database.ParameterScopeImportJob: - // I hate myself. - var version database.TemplateVersion - version, err = api.Database.GetTemplateVersionByJobID(ctx, scopeID) - if err != nil { - break - } - var template database.Template - template, err = api.Database.GetTemplateByID(ctx, version.TemplateID.UUID) - if err != nil { - break - } - resource = version.RBACObject(template) - - case database.ParameterScopeTemplate: - resource, err = api.Database.GetTemplateByID(ctx, scopeID) - default: - err = xerrors.Errorf("Parameter scope %q unsupported", scope) - } - - // Write error payload to rw if we cannot find the resource for the scope - if err != nil { - if xerrors.Is(err, sql.ErrNoRows) { - httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{ - Message: fmt.Sprintf("Scope %q resource %q not found.", scope, scopeID), - }) - } else { - httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ - Message: err.Error(), - }) - } - return nil, false - } - return resource, true -} - func readScopeAndID(ctx context.Context, rw http.ResponseWriter, r *http.Request) (database.ParameterScope, uuid.UUID, bool) { scope := database.ParameterScope(chi.URLParam(r, "scope")) switch scope { From d48a5c3e956dd3374bc21bfc64bb61f51d9ef841 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 11:09:18 -0500 Subject: [PATCH 05/29] Remove rest of duplicate rbac checks --- coderd/database/dbauthz/querier.go | 6 +- coderd/templates.go | 20 ------- coderd/templateversions.go | 92 +----------------------------- coderd/users.go | 89 +---------------------------- coderd/workspaceagents.go | 17 +----- coderd/workspacebuilds.go | 60 +------------------ coderd/workspaces.go | 37 +----------- enterprise/coderd/groups.go | 20 ------- enterprise/coderd/templates.go | 12 ---- 9 files changed, 15 insertions(+), 338 deletions(-) diff --git a/coderd/database/dbauthz/querier.go b/coderd/database/dbauthz/querier.go index 4de696222a828..db4d599ed7cb9 100644 --- a/coderd/database/dbauthz/querier.go +++ b/coderd/database/dbauthz/querier.go @@ -1068,7 +1068,11 @@ func (q *querier) UpdateUserHashedPassword(ctx context.Context, arg database.Upd err = q.authorizeContext(ctx, rbac.ActionUpdate, user.UserDataRBACObject()) if err != nil { - return err + // Admins can update passwords for other users. + err = q.authorizeContext(ctx, rbac.ActionUpdate, user.RBACObject()) + if err != nil { + return err + } } return q.db.UpdateUserHashedPassword(ctx, arg) diff --git a/coderd/templates.go b/coderd/templates.go index aa4a6ddc239a2..9bdc591cc6da1 100644 --- a/coderd/templates.go +++ b/coderd/templates.go @@ -39,11 +39,6 @@ func (api *API) template(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } - createdByNameMap, err := getCreatedByNamesByTemplateIDs(ctx, api.Database, []database.Template{template}) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -79,11 +74,6 @@ func (api *API) deleteTemplate(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = template - if !api.Authorize(r, rbac.ActionDelete, template) { - httpapi.ResourceNotFound(rw) - return - } - // This is just to get the workspace count, so we use a system context to // return ALL workspaces. Not just workspaces the user can view. // nolint:gocritic @@ -156,11 +146,6 @@ func (api *API) postTemplateByOrganization(rw http.ResponseWriter, r *http.Reque defer commitTemplateAudit() defer commitTemplateVersionAudit() - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) { - httpapi.ResourceNotFound(rw) - return - } - if !httpapi.Read(ctx, rw, r, &createTemplate) { return } @@ -462,11 +447,6 @@ func (api *API) patchTemplateMeta(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = template - if !api.Authorize(r, rbac.ActionUpdate, template) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.UpdateTemplateMeta if !httpapi.Read(ctx, rw, r, &req) { return diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 7d9b39226820a..6d176c9e6280f 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -42,14 +42,8 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } - job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -83,12 +77,7 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque ctx := r.Context() var ( templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionUpdate, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { @@ -146,14 +135,8 @@ func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() var ( templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } - job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -205,11 +188,7 @@ func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { func (api *API) templateVersionRichParameters(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() templateVersion := httpmw.TemplateVersionParam(r) - template := httpmw.TemplateParam(r) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } + job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -257,14 +236,8 @@ func (api *API) templateVersionGitAuth(rw http.ResponseWriter, r *http.Request) var ( apiKey = httpmw.APIKey(r) templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } - rawProviders := templateVersion.GitAuthProviders providers := make([]codersdk.TemplateVersionGitAuth, 0) for _, rawProvider := range rawProviders { @@ -356,11 +329,7 @@ func (api *API) templateVersionGitAuth(rw http.ResponseWriter, r *http.Request) func (api *API) templateVersionVariables(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() templateVersion := httpmw.TemplateVersionParam(r) - template := httpmw.TemplateParam(r) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } + job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -399,12 +368,7 @@ func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Reques ctx := r.Context() var ( templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { @@ -455,12 +419,8 @@ func (api *API) postTemplateVersionDryRun(rw http.ResponseWriter, r *http.Reques var ( apiKey = httpmw.APIKey(r) templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } + // We use the workspace RBAC check since we don't want to allow dry runs if // the user can't create workspaces. if !api.Authorize(r, rbac.ActionCreate, @@ -678,15 +638,9 @@ func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Re var ( ctx = r.Context() templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) jobID = chi.URLParam(r, "jobID") ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return database.ProvisionerJob{}, false - } - jobUUID, err := uuid.Parse(jobID) if err != nil { httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ @@ -754,10 +708,6 @@ func (api *API) fetchTemplateVersionDryRunJob(rw http.ResponseWriter, r *http.Re func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } paginationParams, ok := parsePagination(rw, r) if !ok { @@ -860,10 +810,6 @@ func (api *API) templateVersionsByTemplate(rw http.ResponseWriter, r *http.Reque func (api *API) templateVersionByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() template := httpmw.TemplateParam(r) - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } templateVersionName := chi.URLParam(r, "templateversionname") templateVersion, err := api.Database.GetTemplateVersionByTemplateIDAndName(ctx, database.GetTemplateVersionByTemplateIDAndNameParams{ @@ -939,11 +885,6 @@ func (api *API) templateVersionByOrganizationTemplateAndName(rw http.ResponseWri return } - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } - templateVersionName := chi.URLParam(r, "templateversionname") templateVersion, err := api.Database.GetTemplateVersionByTemplateIDAndName(ctx, database.GetTemplateVersionByTemplateIDAndNameParams{ TemplateID: uuid.NullUUID{ @@ -1017,11 +958,6 @@ func (api *API) previousTemplateVersionByOrganizationTemplateAndName(rw http.Res return } - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } - templateVersionName := chi.URLParam(r, "templateversionname") templateVersion, err := api.Database.GetTemplateVersionByTemplateIDAndName(ctx, database.GetTemplateVersionByTemplateIDAndNameParams{ TemplateID: uuid.NullUUID{ @@ -1111,11 +1047,6 @@ func (api *API) patchActiveTemplateVersion(rw http.ResponseWriter, r *http.Reque defer commitAudit() aReq.Old = template - if !api.Authorize(r, rbac.ActionUpdate, template) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.UpdateActiveTemplateVersion if !httpapi.Read(ctx, rw, r, &req) { return @@ -1329,11 +1260,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht } } - if !api.Authorize(r, rbac.ActionRead, file) { - httpapi.ResourceNotFound(rw) - return - } - var templateVersion database.TemplateVersion var provisionerJob database.ProvisionerJob err = api.Database.InTx(func(tx database.Store) error { @@ -1493,14 +1419,8 @@ func (api *API) templateVersionResources(rw http.ResponseWriter, r *http.Request var ( ctx = r.Context() templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } - job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -1532,14 +1452,8 @@ func (api *API) templateVersionLogs(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() templateVersion = httpmw.TemplateVersionParam(r) - template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, templateVersion.RBACObject(template)) { - httpapi.ResourceNotFound(rw) - return - } - job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ diff --git a/coderd/users.go b/coderd/users.go index 54c225e6f53f8..0916a5130eb63 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -279,24 +279,11 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) { }) defer commitAudit() - // Create the user on the site. - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceUser) { - httpapi.Forbidden(rw) - return - } - var req codersdk.CreateUserRequest if !httpapi.Read(ctx, rw, r, &req) { return } - // Create the organization member in the org. - if !api.Authorize(r, rbac.ActionCreate, - rbac.ResourceOrganizationMember.InOrg(req.OrganizationID)) { - httpapi.ResourceNotFound(rw) - return - } - // If password auth is disabled, don't allow new users to be // created with a password! if api.DeploymentValues.DisablePasswordAuth { @@ -397,11 +384,6 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) { aReq.Old = user defer commitAudit() - if !api.Authorize(r, rbac.ActionDelete, rbac.ResourceUser) { - httpapi.Forbidden(rw) - return - } - if auth.Actor.ID == user.ID.String() { httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{ Message: "You cannot delete yourself!", @@ -460,11 +442,6 @@ func (api *API) userByName(rw http.ResponseWriter, r *http.Request) { user := httpmw.UserParam(r) organizationIDs, err := userOrganizationIDs(ctx, api, user) - if !api.Authorize(r, rbac.ActionRead, user) { - httpapi.ResourceNotFound(rw) - return - } - if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ Message: "Internal error fetching user's organizations.", @@ -501,11 +478,6 @@ func (api *API) putUserProfile(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = user - if !api.Authorize(r, rbac.ActionUpdate, user) { - httpapi.ResourceNotFound(rw) - return - } - var params codersdk.UpdateUserProfileRequest if !httpapi.Read(ctx, rw, r, ¶ms) { return @@ -607,11 +579,6 @@ func (api *API) putUserStatus(status database.UserStatus) func(rw http.ResponseW defer commitAudit() aReq.Old = user - if !api.Authorize(r, rbac.ActionDelete, user) { - httpapi.ResourceNotFound(rw) - return - } - if status == database.UserStatusSuspended { // There are some manual protections when suspending a user to // prevent certain situations. @@ -684,11 +651,6 @@ func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = user - if !api.Authorize(r, rbac.ActionUpdate, user.UserDataRBACObject()) { - httpapi.ResourceNotFound(rw) - return - } - if !httpapi.Read(ctx, rw, r, ¶ms) { return } @@ -708,12 +670,7 @@ func (api *API) putUserPassword(rw http.ResponseWriter, r *http.Request) { } // admins can change passwords without sending old_password - if params.OldPassword == "" { - if !api.Authorize(r, rbac.ActionUpdate, user) { - httpapi.Forbidden(rw) - return - } - } else { + if params.OldPassword != "" { // if they send something let's validate it ok, err := userpassword.Compare(string(user.HashedPassword), params.OldPassword) if err != nil { @@ -816,16 +773,6 @@ func (api *API) userRoles(rw http.ResponseWriter, r *http.Request) { return } - // Only include ones we can read from RBAC. - memberships, err = AuthorizeFilter(api.HTTPAuth, r, rbac.ActionRead, memberships) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "Internal error fetching memberships.", - Detail: err.Error(), - }) - return - } - for _, mem := range memberships { // If we can read the org member, include the roles. if err == nil { @@ -876,35 +823,6 @@ func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) { return } - if !api.Authorize(r, rbac.ActionRead, user) { - httpapi.ResourceNotFound(rw) - return - } - - // The member role is always implied. - impliedTypes := append(params.Roles, rbac.RoleMember()) - added, removed := rbac.ChangeRoleSet(user.RBACRoles, impliedTypes) - - // Assigning a role requires the create permission. - if len(added) > 0 && !api.Authorize(r, rbac.ActionCreate, rbac.ResourceRoleAssignment) { - httpapi.Forbidden(rw) - return - } - - // Removing a role requires the delete permission. - if len(removed) > 0 && !api.Authorize(r, rbac.ActionDelete, rbac.ResourceRoleAssignment) { - httpapi.Forbidden(rw) - return - } - - // Just treat adding & removing as "assigning" for now. - for _, roleName := range append(added, removed...) { - if !rbac.CanAssignRole(actorRoles.Actor.Roles, roleName) { - httpapi.Forbidden(rw) - return - } - } - updatedUser, err := api.updateSiteUserRoles(ctx, database.UpdateUserRolesParams{ GrantedRoles: params.Roles, ID: user.ID, @@ -1020,11 +938,6 @@ func (api *API) organizationByUserAndName(rw http.ResponseWriter, r *http.Reques return } - if !api.Authorize(r, rbac.ActionRead, organization) { - httpapi.ResourceNotFound(rw) - return - } - httpapi.Write(ctx, rw, http.StatusOK, convertOrganization(organization)) } diff --git a/coderd/workspaceagents.go b/coderd/workspaceagents.go index 098f83b5358ec..7cf62d07ebd91 100644 --- a/coderd/workspaceagents.go +++ b/coderd/workspaceagents.go @@ -51,11 +51,7 @@ import ( func (api *API) workspaceAgent(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceAgent := httpmw.WorkspaceAgentParam(r) - workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } + dbApps, err := api.Database.GetWorkspaceAppsByAgentID(ctx, workspaceAgent.ID) if err != nil && !xerrors.Is(err, sql.ErrNoRows) { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -325,12 +321,7 @@ func (api *API) workspaceAgentPTY(rw http.ResponseWriter, r *http.Request) { // @Router /workspaceagents/{workspaceagent}/listening-ports [get] func (api *API) workspaceAgentListeningPorts(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - workspace := httpmw.WorkspaceParam(r) workspaceAgent := httpmw.WorkspaceAgentParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } apiAgent, err := convertWorkspaceAgent( api.DERPMap, *api.TailnetCoordinator.Load(), workspaceAgent, nil, api.AgentInactiveDisconnectTimeout, @@ -492,11 +483,7 @@ func (api *API) dialWorkspaceAgentTailnet(r *http.Request, agentID uuid.UUID) (* // @Router /workspaceagents/{workspaceagent}/connection [get] func (api *API) workspaceAgentConnection(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } + httpapi.Write(ctx, rw, http.StatusOK, codersdk.WorkspaceAgentConnectionInfo{ DERPMap: api.DERPMap, }) diff --git a/coderd/workspacebuilds.go b/coderd/workspacebuilds.go index 125bad55b295d..8a238b6994f4d 100644 --- a/coderd/workspacebuilds.go +++ b/coderd/workspacebuilds.go @@ -37,11 +37,6 @@ func (api *API) workspaceBuild(rw http.ResponseWriter, r *http.Request) { workspaceBuild := httpmw.WorkspaceBuildParam(r) workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } - data, err := api.workspaceBuildsData(ctx, []database.Workspace{workspace}, []database.WorkspaceBuild{workspaceBuild}) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -107,11 +102,6 @@ func (api *API) workspaceBuilds(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } - paginationParams, ok := parsePagination(rw, r) if !ok { return @@ -249,11 +239,6 @@ func (api *API) workspaceBuildByBuildNumber(rw http.ResponseWriter, r *http.Requ return } - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } - workspaceBuild, err := api.Database.GetWorkspaceBuildByWorkspaceIDAndBuildNumber(ctx, database.GetWorkspaceBuildByWorkspaceIDAndBuildNumberParams{ WorkspaceID: workspace.ID, BuildNumber: int32(buildNumber), @@ -326,7 +311,9 @@ func (api *API) postWorkspaceBuilds(rw http.ResponseWriter, r *http.Request) { return } - // Rbac action depends on the transition + // Doing this up front saves a lot of work if the user doesn't have permission. + // This is checked again in the dbauthz layer, but the check is cached + // and will be a noop later. var action rbac.Action switch createBuild.Transition { case codersdk.WorkspaceTransitionDelete: @@ -713,11 +700,6 @@ func (api *API) patchCancelWorkspaceBuild(rw http.ResponseWriter, r *http.Reques return } - if !api.Authorize(r, rbac.ActionUpdate, workspace) { - httpapi.ResourceNotFound(rw) - return - } - valid, err := api.verifyUserCanCancelWorkspaceBuilds(ctx, httpmw.APIKey(r).UserID, workspace.TemplateID) if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ @@ -808,18 +790,6 @@ func (api *API) verifyUserCanCancelWorkspaceBuilds(ctx context.Context, userID u func (api *API) workspaceBuildResources(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) - workspace, err := api.Database.GetWorkspaceByID(ctx, workspaceBuild.WorkspaceID) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "No workspace exists for this job.", - }) - return - } - - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } job, err := api.Database.GetProvisionerJobByID(ctx, workspaceBuild.JobID) if err != nil { @@ -843,18 +813,6 @@ func (api *API) workspaceBuildResources(rw http.ResponseWriter, r *http.Request) func (api *API) workspaceBuildParameters(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) - workspace, err := api.Database.GetWorkspaceByID(ctx, workspaceBuild.WorkspaceID) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "No workspace exists for this job.", - }) - return - } - - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } parameters, err := api.Database.GetWorkspaceBuildParameters(ctx, workspaceBuild.ID) if err != nil { @@ -882,18 +840,6 @@ func (api *API) workspaceBuildParameters(rw http.ResponseWriter, r *http.Request func (api *API) workspaceBuildLogs(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspaceBuild := httpmw.WorkspaceBuildParam(r) - workspace, err := api.Database.GetWorkspaceByID(ctx, workspaceBuild.WorkspaceID) - if err != nil { - httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ - Message: "No workspace exists for this job.", - }) - return - } - - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } job, err := api.Database.GetProvisionerJobByID(ctx, workspaceBuild.JobID) if err != nil { diff --git a/coderd/workspaces.go b/coderd/workspaces.go index f97759d0e9d7e..f5c7bfe216422 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -53,10 +53,6 @@ var ( func (api *API) workspace(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } var ( deletedStr = r.URL.Query().Get("include_deleted") @@ -242,10 +238,6 @@ func (api *API) workspaceByOwnerAndName(rw http.ResponseWriter, r *http.Request) }) return } - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } data, err := api.workspaceData(ctx, []database.Workspace{workspace}) if err != nil { @@ -309,6 +301,7 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req defer commitAudit() + // Do this upfront to save work. if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceWorkspace.InOrg(organization.ID).WithOwner(user.ID.String())) { httpapi.ResourceNotFound(rw) @@ -344,10 +337,6 @@ func (api *API) postWorkspacesByOrganization(rw http.ResponseWriter, r *http.Req }) return } - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } if organization.ID != template.OrganizationID { httpapi.Write(ctx, rw, http.StatusUnauthorized, codersdk.Response{ @@ -648,11 +637,6 @@ func (api *API) patchWorkspace(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = workspace - if !api.Authorize(r, rbac.ActionUpdate, workspace) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.UpdateWorkspaceRequest if !httpapi.Read(ctx, rw, r, &req) { return @@ -737,11 +721,6 @@ func (api *API) putWorkspaceAutostart(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = workspace - if !api.Authorize(r, rbac.ActionUpdate, workspace) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.UpdateWorkspaceAutostartRequest if !httpapi.Read(ctx, rw, r, &req) { return @@ -799,11 +778,6 @@ func (api *API) putWorkspaceTTL(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = workspace - if !api.Authorize(r, rbac.ActionUpdate, workspace) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.UpdateWorkspaceTTLRequest if !httpapi.Read(ctx, rw, r, &req) { return @@ -870,11 +844,6 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionUpdate, workspace) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.PutExtendWorkspaceRequest if !httpapi.Read(ctx, rw, r, &req) { return @@ -964,10 +933,6 @@ func (api *API) putExtendWorkspace(rw http.ResponseWriter, r *http.Request) { func (api *API) watchWorkspace(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() workspace := httpmw.WorkspaceParam(r) - if !api.Authorize(r, rbac.ActionRead, workspace) { - httpapi.ResourceNotFound(rw) - return - } sendEvent, senderClosed, err := httpapi.ServerSentEventSender(rw, r) if err != nil { diff --git a/enterprise/coderd/groups.go b/enterprise/coderd/groups.go index b75f29211a13b..de9d280fa28cb 100644 --- a/enterprise/coderd/groups.go +++ b/enterprise/coderd/groups.go @@ -41,11 +41,6 @@ func (api *API) postGroupByOrganization(rw http.ResponseWriter, r *http.Request) ) defer commitAudit() - if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceGroup.InOrg(org.ID)) { - http.NotFound(rw, r) - return - } - var req codersdk.CreateGroupRequest if !httpapi.Read(ctx, rw, r, &req) { return @@ -112,11 +107,6 @@ func (api *API) patchGroup(rw http.ResponseWriter, r *http.Request) { aReq.Old = group.Auditable(currentMembers) - if !api.Authorize(r, rbac.ActionUpdate, group) { - http.NotFound(rw, r) - return - } - var req codersdk.PatchGroupRequest if !httpapi.Read(ctx, rw, r, &req) { return @@ -294,11 +284,6 @@ func (api *API) deleteGroup(rw http.ResponseWriter, r *http.Request) { aReq.Old = group.Auditable(groupMembers) - if !api.Authorize(r, rbac.ActionDelete, group) { - httpapi.ResourceNotFound(rw) - return - } - if group.Name == database.AllUsersGroup { httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ Message: fmt.Sprintf("%q is a reserved group and cannot be deleted!", database.AllUsersGroup), @@ -344,11 +329,6 @@ func (api *API) group(rw http.ResponseWriter, r *http.Request) { group = httpmw.GroupParam(r) ) - if !api.Authorize(r, rbac.ActionRead, group) { - httpapi.ResourceNotFound(rw) - return - } - users, err := api.Database.GetGroupMembers(ctx, group.ID) if err != nil && !xerrors.Is(err, sql.ErrNoRows) { httpapi.InternalServerError(rw, err) diff --git a/enterprise/coderd/templates.go b/enterprise/coderd/templates.go index c75bd9abdfb4d..42dee6a2f0960 100644 --- a/enterprise/coderd/templates.go +++ b/enterprise/coderd/templates.go @@ -32,11 +32,6 @@ func (api *API) templateACL(rw http.ResponseWriter, r *http.Request) { template = httpmw.TemplateParam(r) ) - if !api.Authorize(r, rbac.ActionRead, template) { - httpapi.ResourceNotFound(rw) - return - } - users, err := api.Database.GetTemplateUserRoles(ctx, template.ID) if err != nil { httpapi.InternalServerError(rw, err) @@ -120,13 +115,6 @@ func (api *API) patchTemplateACL(rw http.ResponseWriter, r *http.Request) { defer commitAudit() aReq.Old = template - // Only users who are able to create templates (aka template admins) - // are able to control permissions. - if !api.Authorize(r, rbac.ActionCreate, template) { - httpapi.ResourceNotFound(rw) - return - } - var req codersdk.UpdateTemplateACL if !httpapi.Read(ctx, rw, r, &req) { return From 7672f6e60dad72822c6e808e9009d79f35dc877d Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:03:45 -0500 Subject: [PATCH 06/29] Adding unit tests for rbac checks --- coderd/coderdtest/authorize.go | 51 ++++++++++++++++----------------- coderd/members.go | 1 - coderd/templateversions.go | 15 +--------- coderd/templateversions_test.go | 10 +++++-- coderd/users.go | 1 - coderd/users_test.go | 18 ++++++++---- codersdk/rbac.go | 19 ++++++++++++ 7 files changed, 65 insertions(+), 50 deletions(-) create mode 100644 codersdk/rbac.go diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index e8a85ab52cc12..73c5d43aa5e38 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -3,6 +3,7 @@ package coderdtest import ( "context" "fmt" + "path/filepath" "runtime" "strings" "sync" @@ -22,19 +23,6 @@ import ( "github.com/coder/coder/cryptorand" ) -type CoderSDKObject interface { - codersdk.User -} - -func RBACObject[C CoderSDKObject](o C) rbac.Object { - switch ro := any(o).(type) { - case codersdk.User: - return rbac.ResourceUser.WithID(ro.ID) - default: - panic("unknown object type") - } -} - // RBACAsserter is a helper for asserting that the correct RBAC checks are // performed. This struct is tied to a given user, and only authorizes calls // for this user are checked. @@ -108,7 +96,7 @@ type AuthCall struct { rbac.AuthCall asserted bool - caller string + callers []string } var _ rbac.Authorizer = (*RecordingAuthorizer)(nil) @@ -219,27 +207,38 @@ func (r *RecordingAuthorizer) recordAuthorize(subject rbac.Subject, action rbac. r.Lock() defer r.Unlock() - pc, file, line, ok := runtime.Caller(2) - i := strings.Index(file, "coder") - if i >= 0 { - file = file[i:] - } - caller := fmt.Sprintf("%s:%d", file, line) - if ok { - f := runtime.FuncForPC(pc) - caller += " " + strings.TrimPrefix(f.Name(), "github.com/coder") - } - r.Called = append(r.Called, AuthCall{ AuthCall: rbac.AuthCall{ Actor: subject, Action: action, Object: object, }, - caller: caller, + callers: []string{ + // This is a decent stack trace for debugging. + // Some dbauthz calls are a bit nested, so we skip a few. + caller(2), + caller(3), + caller(4), + caller(5), + }, }) } +func caller(skip int) string { + pc, file, line, ok := runtime.Caller(skip + 1) + i := strings.Index(file, "coder") + if i >= 0 { + file = file[i:] + } + str := fmt.Sprintf("%s:%d", file, line) + if ok { + f := runtime.FuncForPC(pc) + filepath.Base(f.Name()) + str += " | " + filepath.Base(f.Name()) + } + return str +} + func (r *RecordingAuthorizer) Authorize(ctx context.Context, subject rbac.Subject, action rbac.Action, object rbac.Object) error { r.recordAuthorize(subject, action, object) if r.Wrapped == nil { diff --git a/coderd/members.go b/coderd/members.go index 1c0ea5fb00584..293f007dd400d 100644 --- a/coderd/members.go +++ b/coderd/members.go @@ -34,7 +34,6 @@ func (api *API) putMemberRoles(rw http.ResponseWriter, r *http.Request) { organization = httpmw.OrganizationParam(r) member = httpmw.OrganizationMemberParam(r) apiKey = httpmw.APIKey(r) - actorRoles = httpmw.UserAuthorization(r) ) if apiKey.UserID == member.UserID { diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 6d176c9e6280f..35b69b40bacd8 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -1134,10 +1134,8 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht return } - var template database.Template if req.TemplateID != uuid.Nil { - var err error - template, err = api.Database.GetTemplateByID(ctx, req.TemplateID) + _, err := api.Database.GetTemplateByID(ctx, req.TemplateID) if errors.Is(err, sql.ErrNoRows) { httpapi.Write(ctx, rw, http.StatusNotFound, codersdk.Response{ Message: "Template does not exist.", @@ -1153,17 +1151,6 @@ func (api *API) postTemplateVersionsByOrganization(rw http.ResponseWriter, r *ht } } - if template.ID != uuid.Nil { - if !api.Authorize(r, rbac.ActionCreate, template) { - httpapi.ResourceNotFound(rw) - return - } - } else if !api.Authorize(r, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(organization.ID)) { - // Making a new template version is the same permission as creating a new template. - httpapi.ResourceNotFound(rw) - return - } - // Ensures the "owner" is properly applied. tags := provisionerdserver.MutateTags(apiKey.UserID, req.ProvisionerTags) diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 7f9aecbf8e3b1..98bed49ae3352 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -17,6 +17,7 @@ import ( "github.com/coder/coder/coderd/database" "github.com/coder/coder/coderd/gitauth" "github.com/coder/coder/coderd/provisionerdserver" + "github.com/coder/coder/coderd/rbac" "github.com/coder/coder/codersdk" "github.com/coder/coder/examples" "github.com/coder/coder/provisioner/echo" @@ -28,14 +29,19 @@ func TestTemplateVersion(t *testing.T) { t.Parallel() t.Run("Get", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, nil) + client, _, api := coderdtest.NewWithAPI(t, nil) user := coderdtest.CreateFirstUser(t, client) + authz := coderdtest.AssertRBAC(t, api, client).Reset() + version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) + authz.AssertChecked(t, rbac.ActionCreate, rbac.ResourceTemplate.InOrg(user.OrganizationID)) ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - _, err := client.TemplateVersion(ctx, version.ID) + authz.Reset() + tv, err := client.TemplateVersion(ctx, version.ID) + authz.AssertChecked(t, rbac.ActionRead, tv.RBACObjectNoTemplate()) require.NoError(t, err) }) diff --git a/coderd/users.go b/coderd/users.go index 0916a5130eb63..f06eeb770b739 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -798,7 +798,6 @@ func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) { ctx = r.Context() // User is the user to modify. user = httpmw.UserParam(r) - actorRoles = httpmw.UserAuthorization(r) apiKey = httpmw.APIKey(r) auditor = *api.Auditor.Load() aReq, commitAudit = audit.InitRequest[database.User](rw, &audit.RequestParams{ diff --git a/coderd/users_test.go b/coderd/users_test.go index 5e20f78bfb594..fb0254ddcfe4d 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -288,21 +288,27 @@ func TestDeleteUser(t *testing.T) { t.Parallel() t.Run("Works", func(t *testing.T) { t.Parallel() - api := coderdtest.New(t, nil) - user := coderdtest.CreateFirstUser(t, api) - _, another := coderdtest.CreateAnotherUser(t, api, user.OrganizationID) - err := api.DeleteUser(context.Background(), another.ID) + client, _, api := coderdtest.NewWithAPI(t, nil) + user := coderdtest.CreateFirstUser(t, client) + authz := coderdtest.AssertRBAC(t, api, client) + + _, another := coderdtest.CreateAnotherUser(t, client, user.OrganizationID) + err := client.DeleteUser(context.Background(), another.ID) require.NoError(t, err) // Attempt to create a user with the same email and username, and delete them again. - another, err = api.CreateUser(context.Background(), codersdk.CreateUserRequest{ + another, err = client.CreateUser(context.Background(), codersdk.CreateUserRequest{ Email: another.Email, Username: another.Username, Password: "SomeSecurePassword!", OrganizationID: user.OrganizationID, }) require.NoError(t, err) - err = api.DeleteUser(context.Background(), another.ID) + err = client.DeleteUser(context.Background(), another.ID) require.NoError(t, err) + + // RBAC checks + authz.AssertChecked(t, rbac.ActionCreate, rbac.ResourceUser) + authz.AssertChecked(t, rbac.ActionDelete, coderdtest.RBACObject(another)) }) t.Run("NoPermission", func(t *testing.T) { t.Parallel() diff --git a/codersdk/rbac.go b/codersdk/rbac.go new file mode 100644 index 0000000000000..87ee42c38f164 --- /dev/null +++ b/codersdk/rbac.go @@ -0,0 +1,19 @@ +package codersdk + +import "github.com/coder/coder/coderd/rbac" + +// This mirrors modelmethods.go in /database. +// For unit testing, it helps to have these convenience functions for asserting +// rbac authorization calls. + +func (t Template) RBACObject(userACL, groupACL map[string][]rbac.Action) rbac.Object { + return rbac.ResourceTemplate.WithID(t.ID). + InOrg(t.OrganizationID). + WithACLUserList(userACL). + WithGroupACL(groupACL) +} + +// RBACObjectNoTemplate is for orphaned template versions. +func (v TemplateVersion) RBACObjectNoTemplate() rbac.Object { + return rbac.ResourceTemplate.InOrg(v.OrganizationID) +} From 263801b871e1b3e622a96f32ea67672dcfa654db Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:12:37 -0500 Subject: [PATCH 07/29] Add method to unit test rbac --- coderd/coderdtest/authorize.go | 42 ++++++++++++++++++++++++++++----- coderd/templateversions_test.go | 2 +- coderd/users_test.go | 2 +- coderd/workspaces.go | 1 + coderd/workspaces_test.go | 5 +++- codersdk/rbac.go | 19 --------------- codersdk/workspaces.go | 1 + 7 files changed, 44 insertions(+), 28 deletions(-) delete mode 100644 codersdk/rbac.go diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 73c5d43aa5e38..1d835a3067407 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -39,9 +39,10 @@ func (a RBACAsserter) AllCalls() []AuthCall { // AssertChecked will assert a given rbac check was performed. It does not care // about order of checks, or any other checks. This is useful when you do not // care about asserting every check that was performed. -func (a RBACAsserter) AssertChecked(t *testing.T, action rbac.Action, objects ...rbac.Object) { - pairs := make([]ActionObjectPair, 0, len(objects)) - for _, obj := range objects { +func (a RBACAsserter) AssertChecked(t *testing.T, action rbac.Action, objects ...interface{}) { + converted := a.convertObjects(t, objects...) + pairs := make([]ActionObjectPair, 0, len(converted)) + for _, obj := range converted { pairs = append(pairs, a.Recorder.Pair(action, obj)) } a.Recorder.AssertOutOfOrder(t, a.Subject, pairs...) @@ -49,14 +50,40 @@ func (a RBACAsserter) AssertChecked(t *testing.T, action rbac.Action, objects .. // AssertInOrder must be called in the correct order of authz checks. If the objects // or actions are not in the correct order, the test will fail. -func (a RBACAsserter) AssertInOrder(t *testing.T, action rbac.Action, objects ...rbac.Object) { - pairs := make([]ActionObjectPair, 0, len(objects)) - for _, obj := range objects { +func (a RBACAsserter) AssertInOrder(t *testing.T, action rbac.Action, objects ...interface{}) { + converted := a.convertObjects(t, objects...) + pairs := make([]ActionObjectPair, 0, len(converted)) + for _, obj := range converted { pairs = append(pairs, a.Recorder.Pair(action, obj)) } a.Recorder.AssertActor(t, a.Subject, pairs...) } +// convertObjects converts the codersdk types to rbac.Object. Unfortunately +// does not have type safety, and instead uses a t.Fatal to enforce types. +func (a RBACAsserter) convertObjects(t *testing.T, objs ...interface{}) []rbac.Object { + converted := make([]rbac.Object, 0, len(objs)) + for _, obj := range objs { + var robj rbac.Object + switch obj := obj.(type) { + case rbac.Object: + robj = obj + case rbac.Objecter: + robj = obj.RBACObject() + case codersdk.TemplateVersion: + robj = rbac.ResourceTemplate.InOrg(obj.OrganizationID) + case codersdk.User: + robj = rbac.ResourceUser.WithID(obj.ID) + case codersdk.Workspace: + robj = rbac.ResourceWorkspace.WithID(obj.ID).InOrg(obj.OrganizationID).WithOwner(obj.OwnerID.String()) + default: + t.Fatalf("unsupported type %T to convert to rbac.Object, add the implementation", obj) + } + converted = append(converted, robj) + } + return converted +} + // Reset will clear all previously recorded authz calls. func (a RBACAsserter) Reset() RBACAsserter { a.Recorder.Reset() @@ -64,6 +91,9 @@ func (a RBACAsserter) Reset() RBACAsserter { } func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsserter { + if client.SessionToken() == "" { + t.Fatal("client must be logged in") + } recorder, ok := api.Authorizer.(*RecordingAuthorizer) if !ok { t.Fatal("expected RecordingAuthorizer") diff --git a/coderd/templateversions_test.go b/coderd/templateversions_test.go index 98bed49ae3352..176c338f5ed1c 100644 --- a/coderd/templateversions_test.go +++ b/coderd/templateversions_test.go @@ -41,7 +41,7 @@ func TestTemplateVersion(t *testing.T) { authz.Reset() tv, err := client.TemplateVersion(ctx, version.ID) - authz.AssertChecked(t, rbac.ActionRead, tv.RBACObjectNoTemplate()) + authz.AssertChecked(t, rbac.ActionRead, tv) require.NoError(t, err) }) diff --git a/coderd/users_test.go b/coderd/users_test.go index fb0254ddcfe4d..7f8283cdf018f 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -308,7 +308,7 @@ func TestDeleteUser(t *testing.T) { // RBAC checks authz.AssertChecked(t, rbac.ActionCreate, rbac.ResourceUser) - authz.AssertChecked(t, rbac.ActionDelete, coderdtest.RBACObject(another)) + authz.AssertChecked(t, rbac.ActionDelete, another) }) t.Run("NoPermission", func(t *testing.T) { t.Parallel() diff --git a/coderd/workspaces.go b/coderd/workspaces.go index f5c7bfe216422..f84d7d6d9d345 100644 --- a/coderd/workspaces.go +++ b/coderd/workspaces.go @@ -1148,6 +1148,7 @@ func convertWorkspace( UpdatedAt: workspace.UpdatedAt, OwnerID: workspace.OwnerID, OwnerName: owner.Username, + OrganizationID: workspace.OrganizationID, TemplateID: workspace.TemplateID, LatestBuild: workspaceBuild, TemplateName: template.Name, diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index d652b65129bae..aea0bab3af8fb 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -36,8 +36,9 @@ func TestWorkspace(t *testing.T) { t.Run("OK", func(t *testing.T) { t.Parallel() - client := coderdtest.New(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) + client, _, api := coderdtest.NewWithAPI(t, &coderdtest.Options{IncludeProvisionerDaemon: true}) user := coderdtest.CreateFirstUser(t, client) + authz := coderdtest.AssertRBAC(t, api, client) version := coderdtest.CreateTemplateVersion(t, client, user.OrganizationID, nil) coderdtest.AwaitTemplateVersionJob(t, client, version.ID) template := coderdtest.CreateTemplate(t, client, user.OrganizationID, version.ID) @@ -46,7 +47,9 @@ func TestWorkspace(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() + authz.Reset() ws, err := client.Workspace(ctx, workspace.ID) + authz.AssertChecked(t, rbac.ActionRead, ws) require.NoError(t, err) require.Equal(t, user.UserID, ws.LatestBuild.InitiatorID) require.Equal(t, codersdk.BuildReasonInitiator, ws.LatestBuild.Reason) diff --git a/codersdk/rbac.go b/codersdk/rbac.go deleted file mode 100644 index 87ee42c38f164..0000000000000 --- a/codersdk/rbac.go +++ /dev/null @@ -1,19 +0,0 @@ -package codersdk - -import "github.com/coder/coder/coderd/rbac" - -// This mirrors modelmethods.go in /database. -// For unit testing, it helps to have these convenience functions for asserting -// rbac authorization calls. - -func (t Template) RBACObject(userACL, groupACL map[string][]rbac.Action) rbac.Object { - return rbac.ResourceTemplate.WithID(t.ID). - InOrg(t.OrganizationID). - WithACLUserList(userACL). - WithGroupACL(groupACL) -} - -// RBACObjectNoTemplate is for orphaned template versions. -func (v TemplateVersion) RBACObjectNoTemplate() rbac.Object { - return rbac.ResourceTemplate.InOrg(v.OrganizationID) -} diff --git a/codersdk/workspaces.go b/codersdk/workspaces.go index c41fb91f9752c..fd1fe4d02811e 100644 --- a/codersdk/workspaces.go +++ b/codersdk/workspaces.go @@ -22,6 +22,7 @@ type Workspace struct { UpdatedAt time.Time `json:"updated_at" format:"date-time"` OwnerID uuid.UUID `json:"owner_id" format:"uuid"` OwnerName string `json:"owner_name"` + OrganizationID uuid.UUID `json:"organization_id" format:"uuid"` TemplateID uuid.UUID `json:"template_id" format:"uuid"` TemplateName string `json:"template_name"` TemplateDisplayName string `json:"template_display_name"` From 893198a5df08544283ce363d60ff60c590907e61 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:13:15 -0500 Subject: [PATCH 08/29] Add comment --- coderd/workspaces_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/workspaces_test.go b/coderd/workspaces_test.go index aea0bab3af8fb..a40cf0fd21d73 100644 --- a/coderd/workspaces_test.go +++ b/coderd/workspaces_test.go @@ -47,7 +47,7 @@ func TestWorkspace(t *testing.T) { ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) defer cancel() - authz.Reset() + authz.Reset() // Reset all previous checks done in setup. ws, err := client.Workspace(ctx, workspace.ID) authz.AssertChecked(t, rbac.ActionRead, ws) require.NoError(t, err) From 6b2c3f9eac6d220a4e30ac86ae653716a55d22b8 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:16:54 -0500 Subject: [PATCH 09/29] Add comments --- coderd/coderdtest/authorize.go | 74 +++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 1d835a3067407..525e25601f0d8 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -32,6 +32,44 @@ type RBACAsserter struct { Recorder *RecordingAuthorizer } +// AssertRBAC returns an RBACAsserter for the given user. This asserter will +// allow asserting that the correct RBAC checks are performed for the given user. +// All checks that are not run against this user will be ignored. +func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsserter { + if client.SessionToken() == "" { + t.Fatal("client must be logged in") + } + recorder, ok := api.Authorizer.(*RecordingAuthorizer) + if !ok { + t.Fatal("expected RecordingAuthorizer") + } + + // We use the database directly to not cause additional auth checks on behalf + // of the user. This does add authz checks on behalf of the system user, but + // it is hard to avoid that. + ctx := dbauthz.AsSystemRestricted(context.Background()) + token := client.SessionToken() + parts := strings.Split(token, "-") + key, err := api.Database.GetAPIKeyByID(ctx, parts[0]) + require.NoError(t, err, "fetch client api key") + + roles, err := api.Database.GetAuthorizationUserRoles(ctx, key.UserID) + require.NoError(t, err, "fetch user roles") + + return RBACAsserter{ + Subject: rbac.Subject{ + ID: key.UserID.String(), + Roles: rbac.RoleNames(roles.Roles), + Groups: roles.Groups, + Scope: rbac.ScopeName(key.Scope), + }, + Recorder: recorder, + } +} + +// AllCalls is for debugging. If you are not sure where calls are coming from, +// call this and use a debugger or print them. They have small callstacks +// on them to help locate the 'Authorize' call. func (a RBACAsserter) AllCalls() []AuthCall { return a.Recorder.AllCalls(&a.Subject) } @@ -85,48 +123,18 @@ func (a RBACAsserter) convertObjects(t *testing.T, objs ...interface{}) []rbac.O } // Reset will clear all previously recorded authz calls. +// This is helpful when wanting to ignore checks run in test setup. func (a RBACAsserter) Reset() RBACAsserter { a.Recorder.Reset() return a } -func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsserter { - if client.SessionToken() == "" { - t.Fatal("client must be logged in") - } - recorder, ok := api.Authorizer.(*RecordingAuthorizer) - if !ok { - t.Fatal("expected RecordingAuthorizer") - } - - // We use the database directly to not cause additional auth checks on behalf - // of the user. This does add authz checks on behalf of the system user, but - // it is hard to avoid that. - ctx := dbauthz.AsSystemRestricted(context.Background()) - token := client.SessionToken() - parts := strings.Split(token, "-") - key, err := api.Database.GetAPIKeyByID(ctx, parts[0]) - require.NoError(t, err, "fetch client api key") - - roles, err := api.Database.GetAuthorizationUserRoles(ctx, key.UserID) - require.NoError(t, err, "fetch user roles") - - return RBACAsserter{ - Subject: rbac.Subject{ - ID: key.UserID.String(), - Roles: rbac.RoleNames(roles.Roles), - Groups: roles.Groups, - Scope: rbac.ScopeName(key.Scope), - }, - Recorder: recorder, - } -} - type AuthCall struct { rbac.AuthCall asserted bool - callers []string + // callers is a small stack trace for debugging. + callers []string } var _ rbac.Authorizer = (*RecordingAuthorizer)(nil) From 84ba18d8840634abfe0c096815e2e942378a782a Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:23:24 -0500 Subject: [PATCH 10/29] Add comment --- coderd/coderdtest/authorize.go | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 525e25601f0d8..6ba5d7482e598 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -70,6 +70,10 @@ func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsse // AllCalls is for debugging. If you are not sure where calls are coming from, // call this and use a debugger or print them. They have small callstacks // on them to help locate the 'Authorize' call. +// Only calls to Authorize by the given subject will be returned. +// Note that duplicate rbac calls are handled by the rbac.Cacher(), but +// will be recorded twice. So AllCalls() returns calls regardless if they +// were returned from the cached or not. func (a RBACAsserter) AllCalls() []AuthCall { return a.Recorder.AllCalls(&a.Subject) } From a5ff7fc5cb83b5783e1b9d47b3ebce7fb4516e31 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:33:44 -0500 Subject: [PATCH 11/29] Make gen --- coderd/apidoc/docs.go | 4 ++++ coderd/apidoc/swagger.json | 4 ++++ docs/api/schemas.md | 3 +++ docs/api/workspaces.md | 4 ++++ 4 files changed, 15 insertions(+) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 67075e77f6a61..74fb18f0dc42e 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -8504,6 +8504,10 @@ const docTemplate = `{ "name": { "type": "string" }, + "organization_id": { + "type": "string", + "format": "uuid" + }, "outdated": { "type": "boolean" }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 2697a8ee2205a..074a6c4ab5ebc 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -7652,6 +7652,10 @@ "name": { "type": "string" }, + "organization_id": { + "type": "string", + "format": "uuid" + }, "outdated": { "type": "boolean" }, diff --git a/docs/api/schemas.md b/docs/api/schemas.md index cff9081317ba7..6757825721bd0 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -4338,6 +4338,7 @@ Parameter represents a set value for the scope. "workspace_owner_name": "string" }, "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "outdated": true, "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", "owner_name": "string", @@ -4361,6 +4362,7 @@ Parameter represents a set value for the scope. | `last_used_at` | string | false | | | | `latest_build` | [codersdk.WorkspaceBuild](#codersdkworkspacebuild) | false | | | | `name` | string | false | | | +| `organization_id` | string | false | | | | `outdated` | boolean | false | | | | `owner_id` | string | false | | | | `owner_name` | string | false | | | @@ -5222,6 +5224,7 @@ Parameter represents a set value for the scope. "workspace_owner_name": "string" }, "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "outdated": true, "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", "owner_name": "string", diff --git a/docs/api/workspaces.md b/docs/api/workspaces.md index ca19ba4f54dcb..e37c0ff7cd9ca 100644 --- a/docs/api/workspaces.md +++ b/docs/api/workspaces.md @@ -175,6 +175,7 @@ curl -X POST http://coder-server:8080/api/v2/organizations/{organization}/member "workspace_owner_name": "string" }, "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "outdated": true, "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", "owner_name": "string", @@ -344,6 +345,7 @@ curl -X GET http://coder-server:8080/api/v2/users/{user}/workspace/{workspacenam "workspace_owner_name": "string" }, "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "outdated": true, "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", "owner_name": "string", @@ -532,6 +534,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces \ "workspace_owner_name": "string" }, "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "outdated": true, "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", "owner_name": "string", @@ -702,6 +705,7 @@ curl -X GET http://coder-server:8080/api/v2/workspaces/{workspace} \ "workspace_owner_name": "string" }, "name": "string", + "organization_id": "7c60d51f-b44e-4682-87d6-449835ea4de6", "outdated": true, "owner_id": "8826ee2e-7933-4665-aef2-2393f84a0d05", "owner_name": "string", From bb788a465b97c2104c0ed7665a1c41fefa7c3041 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Fri, 17 Mar 2023 12:34:26 -0500 Subject: [PATCH 12/29] Make golden files --- cli/testdata/coder_list_--output_json.golden | 1 + 1 file changed, 1 insertion(+) diff --git a/cli/testdata/coder_list_--output_json.golden b/cli/testdata/coder_list_--output_json.golden index 9a39ed4f9c3dc..6ea0ced1835ee 100644 --- a/cli/testdata/coder_list_--output_json.golden +++ b/cli/testdata/coder_list_--output_json.golden @@ -5,6 +5,7 @@ "updated_at": "[timestamp]", "owner_id": "[first user ID]", "owner_name": "testuser", + "organization_id": "[first org ID]", "template_id": "[template ID]", "template_name": "test-template", "template_display_name": "", From c0f6ff0ffbbf7b4c0d320b0abb83d21678101ee5 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 09:37:48 -0500 Subject: [PATCH 13/29] linting --- coderd/coderdtest/authorize.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 6ba5d7482e598..ecc7ce87f329d 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -47,6 +47,7 @@ func AssertRBAC(t *testing.T, api *coderd.API, client *codersdk.Client) RBACAsse // We use the database directly to not cause additional auth checks on behalf // of the user. This does add authz checks on behalf of the system user, but // it is hard to avoid that. + // nolint:gocritic ctx := dbauthz.AsSystemRestricted(context.Background()) token := client.SessionToken() parts := strings.Split(token, "-") From f7842ee1a292e2db767be7f08f145e0b210e99e4 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 10:00:56 -0500 Subject: [PATCH 14/29] linting --- coderd/apikey.go | 3 --- coderd/templateversions.go | 16 ++++------------ coderd/users.go | 1 - 3 files changed, 4 insertions(+), 16 deletions(-) diff --git a/coderd/apikey.go b/coderd/apikey.go index 64c296f3912fe..c05f0205dc80f 100644 --- a/coderd/apikey.go +++ b/coderd/apikey.go @@ -55,7 +55,6 @@ func (api *API) postToken(rw http.ResponseWriter, r *http.Request) { aReq.Old = database.APIKey{} defer commitAudit() - var createToken codersdk.CreateTokenRequest if !httpapi.Read(ctx, rw, r, &createToken) { return @@ -308,7 +307,6 @@ func (api *API) tokens(rw http.ResponseWriter, r *http.Request) { func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) { var ( ctx = r.Context() - user = httpmw.UserParam(r) keyID = chi.URLParam(r, "keyid") auditor = api.Auditor.Load() aReq, commitAudit = audit.InitRequest[database.APIKey](rw, &audit.RequestParams{ @@ -325,7 +323,6 @@ func (api *API) deleteAPIKey(rw http.ResponseWriter, r *http.Request) { aReq.Old = key defer commitAudit() - err = api.Database.DeleteAPIKeyByID(ctx, keyID) if errors.Is(err, sql.ErrNoRows) { httpapi.ResourceNotFound(rw) diff --git a/coderd/templateversions.go b/coderd/templateversions.go index 35b69b40bacd8..59f42c8150df1 100644 --- a/coderd/templateversions.go +++ b/coderd/templateversions.go @@ -40,9 +40,7 @@ import ( // @Router /templateversions/{templateversion} [get] func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - var ( - templateVersion = httpmw.TemplateVersionParam(r) - ) + templateVersion := httpmw.TemplateVersionParam(r) job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { @@ -75,9 +73,7 @@ func (api *API) templateVersion(rw http.ResponseWriter, r *http.Request) { // @Router /templateversions/{templateversion}/cancel [patch] func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - var ( - templateVersion = httpmw.TemplateVersionParam(r) - ) + templateVersion := httpmw.TemplateVersionParam(r) job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { @@ -133,9 +129,7 @@ func (api *API) patchCancelTemplateVersion(rw http.ResponseWriter, r *http.Reque // @Router /templateversions/{templateversion}/schema [get] func (api *API) templateVersionSchema(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - var ( - templateVersion = httpmw.TemplateVersionParam(r) - ) + templateVersion := httpmw.TemplateVersionParam(r) job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { @@ -366,9 +360,7 @@ func (api *API) templateVersionVariables(rw http.ResponseWriter, r *http.Request // @Router /templateversions/{templateversion}/parameters [get] func (api *API) templateVersionParameters(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() - var ( - templateVersion = httpmw.TemplateVersionParam(r) - ) + templateVersion := httpmw.TemplateVersionParam(r) job, err := api.Database.GetProvisionerJobByID(ctx, templateVersion.JobID) if err != nil { diff --git a/coderd/users.go b/coderd/users.go index f06eeb770b739..26b3f557c5d9f 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -441,7 +441,6 @@ func (api *API) userByName(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() user := httpmw.UserParam(r) organizationIDs, err := userOrganizationIDs(ctx, api, user) - if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ Message: "Internal error fetching user's organizations.", From b6130e3e00312c8a3a9ee00d751caf40da347529 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 10:21:19 -0500 Subject: [PATCH 15/29] linting --- coderd/coderdtest/authorize.go | 11 ----------- coderd/organizations.go | 2 +- 2 files changed, 1 insertion(+), 12 deletions(-) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index ecc7ce87f329d..45de5dd1213af 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -316,17 +316,6 @@ func (r *RecordingAuthorizer) Reset() { r.Called = nil } -// lastCall is implemented to support legacy tests. -// Deprecated -func (r *RecordingAuthorizer) lastCall() *AuthCall { - r.RLock() - defer r.RUnlock() - if len(r.Called) == 0 { - return nil - } - return &r.Called[len(r.Called)-1] -} - // PreparedRecorder is the prepared version of the RecordingAuthorizer. // It records the Authorize() calls to the original recorder. If the caller // uses CompileToSQL, all recording stops. This is to support parity between diff --git a/coderd/organizations.go b/coderd/organizations.go index 391442db75730..ac7e61faa7275 100644 --- a/coderd/organizations.go +++ b/coderd/organizations.go @@ -24,7 +24,7 @@ import ( // @Param organization path string true "Organization ID" format(uuid) // @Success 200 {object} codersdk.Organization // @Router /organizations/{organization} [get] -func (api *API) organization(rw http.ResponseWriter, r *http.Request) { +func (API) organization(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) From 8b744acd8d5dbf252f0744f731b9b6f2ea5322c9 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 10:25:43 -0500 Subject: [PATCH 16/29] Merge lost a config section --- coderd/coderd.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/coderd/coderd.go b/coderd/coderd.go index 64b7a8c80b6a4..ac277d057bb71 100644 --- a/coderd/coderd.go +++ b/coderd/coderd.go @@ -219,7 +219,9 @@ func New(options *Options) *API { if options.Auditor == nil { options.Auditor = audit.NewNop() } - + if options.SSHConfig.HostnamePrefix == "" { + options.SSHConfig.HostnamePrefix = "coder." + } if options.SetUserGroups == nil { options.SetUserGroups = func(context.Context, database.Store, uuid.UUID, []string) error { return nil } } From 55f01c5464dad310de14a1887822c527576b09eb Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 10:27:32 -0500 Subject: [PATCH 17/29] Linting --- coderd/coderdtest/authorize.go | 1 - 1 file changed, 1 deletion(-) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 45de5dd1213af..678a88f60a99e 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -276,7 +276,6 @@ func caller(skip int) string { str := fmt.Sprintf("%s:%d", file, line) if ok { f := runtime.FuncForPC(pc) - filepath.Base(f.Name()) str += " | " + filepath.Base(f.Name()) } return str From 4965c10e3f7bbf9ad9a33f1a6bc48006f08cccb3 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 10:33:59 -0500 Subject: [PATCH 18/29] Make gen --- coderd/apidoc/swagger.json | 17511 ++++++++++++++++--------------- coderd/organizations.go | 2 +- site/src/api/typesGenerated.ts | 1 + 3 files changed, 9202 insertions(+), 8312 deletions(-) diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 074a6c4ab5ebc..b180325de3318 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1,8410 +1,9299 @@ { - "swagger": "2.0", - "info": { - "description": "Coderd is the service created by running coder server. It is a thin API that connects workspaces, provisioners and users. coderd stores its state in Postgres and is the only service that communicates with Postgres.", - "title": "Coder API", - "termsOfService": "https://coder.com/legal/terms-of-service", - "contact": { - "name": "API Support", - "url": "https://coder.com", - "email": "support@coder.com" - }, - "license": { - "name": "AGPL-3.0", - "url": "https://github.com/coder/coder/blob/main/LICENSE" - }, - "version": "2.0" - }, - "basePath": "/api/v2", - "paths": { - "/": { - "get": { - "produces": ["application/json"], - "tags": ["General"], - "summary": "API root handler", - "operationId": "api-root-handler", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/appearance": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get appearance", - "operationId": "get-appearance", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AppearanceConfig" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update appearance", - "operationId": "update-appearance", - "parameters": [ - { - "description": "Update appearance request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" - } - } - } - } - }, - "/applications/auth-redirect": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Applications"], - "summary": "Redirect to URI with encrypted API key", - "operationId": "redirect-to-uri-with-encrypted-api-key", - "parameters": [ - { - "type": "string", - "description": "Redirect destination", - "name": "redirect_uri", - "in": "query" - } - ], - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/applications/host": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Applications"], - "summary": "Get applications host", - "operationId": "get-applications-host", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AppHostResponse" - } - } - } - } - }, - "/audit": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Audit"], - "summary": "Get audit logs", - "operationId": "get-audit-logs", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "q", - "in": "query", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuditLogResponse" - } - } - } - } - }, - "/audit/testgenerate": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Audit"], - "summary": "Generate fake audit log", - "operationId": "generate-fake-audit-log", - "parameters": [ - { - "description": "Audit log request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/authcheck": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Authorization"], - "summary": "Check authorization", - "operationId": "check-authorization", - "parameters": [ - { - "description": "Authorization request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.AuthorizationRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuthorizationResponse" - } - } - } - } - }, - "/buildinfo": { - "get": { - "produces": ["application/json"], - "tags": ["General"], - "summary": "Build info", - "operationId": "build-info", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.BuildInfoResponse" - } - } - } - } - }, - "/csp/reports": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["General"], - "summary": "Report CSP violations", - "operationId": "report-csp-violations", - "parameters": [ - { - "description": "Violation report", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.cspViolation" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/debug/coordinator": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["text/html"], - "tags": ["Debug"], - "summary": "Debug Info Wireguard Coordinator", - "operationId": "debug-info-wireguard-coordinator", - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/deployment/config": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get deployment config", - "operationId": "get-deployment-config", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentConfig" - } - } - } - } - }, - "/deployment/ssh": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "SSH Config", - "operationId": "ssh-config", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.SSHConfigResponse" - } - } - } - } - }, - "/deployment/stats": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get deployment stats", - "operationId": "get-deployment-stats", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentStats" - } - } - } - } - }, - "/entitlements": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get entitlements", - "operationId": "get-entitlements", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Entitlements" - } - } - } - } - }, - "/experiments": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get experiments", - "operationId": "get-experiments", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Experiment" - } - } - } - } - } - }, - "/files": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "Swagger notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", - "consumes": ["application/x-tar"], - "produces": ["application/json"], - "tags": ["Files"], - "summary": "Upload file", - "operationId": "upload-file", - "parameters": [ - { - "type": "string", - "default": "application/x-tar", - "description": "Content-Type must be `application/x-tar`", - "name": "Content-Type", - "in": "header", - "required": true - }, - { - "type": "file", - "description": "File to be uploaded", - "name": "file", - "in": "formData", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.UploadResponse" - } - } - } - } - }, - "/files/{fileID}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Files"], - "summary": "Get file by ID", - "operationId": "get-file-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "File ID", - "name": "fileID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/groups": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get groups", - "operationId": "get-groups", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - } - }, - "/groups/{group}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get group by name", - "operationId": "get-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Delete group by name", - "operationId": "delete-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update group by name", - "operationId": "update-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/insights/daus": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Insights"], - "summary": "Get deployment DAUs", - "operationId": "get-deployment-daus", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentDAUsResponse" - } - } - } - } - }, - "/licenses": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get licenses", - "operationId": "get-licenses", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.License" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Add new license", - "operationId": "add-new-license", - "parameters": [ - { - "description": "Add license request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.AddLicenseRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.License" - } - } - } - } - }, - "/licenses/{id}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Delete license", - "operationId": "delete-license", - "parameters": [ - { - "type": "string", - "format": "number", - "description": "License ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/organizations": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Create organization", - "operationId": "create-organization", - "parameters": [ - { - "description": "Create organization request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateOrganizationRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/organizations/{organization}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Organizations"], - "summary": "Get organization by ID", - "operationId": "get-organization-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/organizations/{organization}/groups": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get groups by organization", - "operationId": "get-groups-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Create group for organization", - "operationId": "create-group-for-organization", - "parameters": [ - { - "description": "Create group request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateGroupRequest" - } - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/organizations/{organization}/groups/{groupName}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get group by organization and group name", - "operationId": "get-group-by-organization-and-group-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group name", - "name": "groupName", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/organizations/{organization}/members/roles": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Get member roles by organization", - "operationId": "get-member-roles-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AssignableRoles" - } - } - } - } - } - }, - "/organizations/{organization}/members/{user}/roles": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Assign role to organization member", - "operationId": "assign-role-to-organization-member", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update roles request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateRoles" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.OrganizationMember" - } - } - } - } - }, - "/organizations/{organization}/members/{user}/workspaces": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Create user workspace by organization", - "operationId": "create-user-workspace-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Username, UUID, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Create workspace request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/organizations/{organization}/provisionerdaemons": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get provisioner daemons", - "operationId": "get-provisioner-daemons", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerDaemon" - } - } - } - } - } - }, - "/organizations/{organization}/provisionerdaemons/serve": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Enterprise"], - "summary": "Serve provisioner daemon", - "operationId": "serve-provisioner-daemon", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/organizations/{organization}/templates": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get templates by organization", - "operationId": "get-templates-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Create template by organization", - "operationId": "create-template-by-organization", - "parameters": [ - { - "description": "Request body", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateRequest" - } - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/organizations/{organization}/templates/examples": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template examples by organization", - "operationId": "get-template-examples-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateExample" - } - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get templates by organization and template name", - "operationId": "get-templates-by-organization-and-template-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version by organization, template, and name", - "operationId": "get-template-version-by-organization-template-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get previous template version by organization, template, and name", - "operationId": "get-previous-template-version-by-organization-template-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/organizations/{organization}/templateversions": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Create template version by organization", - "operationId": "create-template-version-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "description": "Create template version request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateVersionRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/parameters/{scope}/{id}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Parameters"], - "summary": "Get parameters", - "operationId": "get-parameters", - "parameters": [ - { - "enum": ["template", "workspace", "import_job"], - "type": "string", - "description": "Scope", - "name": "scope", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Parameter" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Parameters"], - "summary": "Create parameter", - "operationId": "create-parameter", - "parameters": [ - { - "description": "Parameter request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - { - "enum": ["template", "workspace", "import_job"], - "type": "string", - "description": "Scope", - "name": "scope", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Parameter" - } - } - } - } - }, - "/parameters/{scope}/{id}/{name}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Parameters"], - "summary": "Delete parameter", - "operationId": "delete-parameter", - "parameters": [ - { - "enum": ["template", "workspace", "import_job"], - "type": "string", - "description": "Scope", - "name": "scope", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "ID", - "name": "id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Name", - "name": "name", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/replicas": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get active replicas", - "operationId": "get-active-replicas", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Replica" - } - } - } - } - } - }, - "/scim/v2/Users": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/scim+json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Get users", - "operationId": "scim-get-users", - "responses": { - "200": { - "description": "OK" - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Create new user", - "operationId": "scim-create-new-user", - "parameters": [ - { - "description": "New user", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - } - } - }, - "/scim/v2/Users/{id}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/scim+json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Get user by ID", - "operationId": "scim-get-user-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "404": { - "description": "Not Found" - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/scim+json"], - "tags": ["Enterprise"], - "summary": "SCIM 2.0: Update user account", - "operationId": "scim-update-user-status", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Update user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/templates/{template}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template metadata by ID", - "operationId": "get-template-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Delete template by ID", - "operationId": "delete-template-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Update template metadata by ID", - "operationId": "update-template-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/templates/{template}/acl": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get template ACLs", - "operationId": "get-template-acls", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateUser" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Update template ACL", - "operationId": "update-template-acl", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "description": "Update template request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateTemplateACL" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/daus": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template DAUs by ID", - "operationId": "get-template-daus-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateDAUsResponse" - } - } - } - } - }, - "/templates/{template}/versions": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "List template versions by template ID", - "operationId": "list-template-versions-by-template-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Update active template version by template ID", - "operationId": "update-active-template-version-by-template-id", - "parameters": [ - { - "description": "Modified template version", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateActiveTemplateVersion" - } - }, - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/versions/{templateversionname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version by template ID and name", - "operationId": "get-template-version-by-template-id-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - } - }, - "/templateversions/{templateversion}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version by ID", - "operationId": "get-template-version-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/templateversions/{templateversion}/cancel": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Cancel template version by ID", - "operationId": "cancel-template-version-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Create template version dry-run", - "operationId": "create-template-version-dry-run", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "description": "Dry-run request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version dry-run by job ID", - "operationId": "get-template-version-dry-run-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}/cancel": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Cancel template version dry-run by job ID", - "operationId": "cancel-template-version-dry-run-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version dry-run logs by job ID", - "operationId": "get-template-version-dry-run-logs-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template version dry-run resources by job ID", - "operationId": "get-template-version-dry-run-resources-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/templateversions/{templateversion}/gitauth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get git auth by template version", - "operationId": "get-git-auth-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionGitAuth" - } - } - } - } - } - }, - "/templateversions/{templateversion}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get logs by template version", - "operationId": "get-logs-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } - } - } - } - } - }, - "/templateversions/{templateversion}/parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get parameters by template version", - "operationId": "get-parameters-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/parameter.ComputedValue" - } - } - } - } - } - }, - "/templateversions/{templateversion}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get resources by template version", - "operationId": "get-resources-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/templateversions/{templateversion}/rich-parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get rich parameters by template version", - "operationId": "get-rich-parameters-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionParameter" - } - } - } - } - } - }, - "/templateversions/{templateversion}/schema": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get schema by template version", - "operationId": "get-schema-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ParameterSchema" - } - } - } - } - } - }, - "/templateversions/{templateversion}/variables": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Templates"], - "summary": "Get template variables by template version", - "operationId": "get-template-variables-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionVariable" - } - } - } - } - } - }, - "/updatecheck": { - "get": { - "produces": ["application/json"], - "tags": ["General"], - "summary": "Update check", - "operationId": "update-check", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UpdateCheckResponse" - } - } - } - } - }, - "/users": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get users", - "operationId": "get-users", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "q", - "in": "query" - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.GetUsersResponse" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Create new user", - "operationId": "create-new-user", - "parameters": [ - { - "description": "Create user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateUserRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/authmethods": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get authentication methods", - "operationId": "get-authentication-methods", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuthMethods" - } - } - } - } - }, - "/users/first": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Check initial user created", - "operationId": "check-initial-user-created", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Create initial user", - "operationId": "create-initial-user", - "parameters": [ - { - "description": "First user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateFirstUserRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.CreateFirstUserResponse" - } - } - } - } - }, - "/users/login": { - "post": { - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Authorization"], - "summary": "Log in user", - "operationId": "log-in-user", - "parameters": [ - { - "description": "Login request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.LoginWithPasswordRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.LoginWithPasswordResponse" - } - } - } - } - }, - "/users/logout": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Log out user", - "operationId": "log-out-user", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/users/oauth2/github/callback": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Users"], - "summary": "OAuth 2.0 GitHub Callback", - "operationId": "oauth-20-github-callback", - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/users/oidc/callback": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Users"], - "summary": "OpenID Connect Callback", - "operationId": "openid-connect-callback", - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/users/roles": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Members"], - "summary": "Get site member roles", - "operationId": "get-site-member-roles", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AssignableRoles" - } - } - } - } - } - }, - "/users/{user}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get user by name", - "operationId": "get-user-by-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Delete user", - "operationId": "delete-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/gitsshkey": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get user Git SSH key", - "operationId": "get-user-git-ssh-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.GitSSHKey" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Regenerate user SSH key", - "operationId": "regenerate-user-ssh-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.GitSSHKey" - } - } - } - } - }, - "/users/{user}/keys": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Create new session key", - "operationId": "create-new-session-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" - } - } - } - } - }, - "/users/{user}/keys/tokens": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get user tokens", - "operationId": "get-user-tokens", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Create token API key", - "operationId": "create-token-api-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Create token request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTokenRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" - } - } - } - } - }, - "/users/{user}/keys/tokens/tokenconfig": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["General"], - "summary": "Get token config", - "operationId": "get-token-config", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TokenConfig" - } - } - } - } - }, - "/users/{user}/keys/tokens/{keyname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get API key by token name", - "operationId": "get-api-key-by-token-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "string", - "description": "Key Name", - "name": "keyname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - } - }, - "/users/{user}/keys/{keyid}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get API key by ID", - "operationId": "get-api-key-by-id", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Key ID", - "name": "keyid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Users"], - "summary": "Delete API key", - "operationId": "delete-api-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Key ID", - "name": "keyid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/users/{user}/organizations": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get organizations by user", - "operationId": "get-organizations-by-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - } - }, - "/users/{user}/organizations/{organizationname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get organization by user and organization name", - "operationId": "get-organization-by-user-and-organization-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Organization name", - "name": "organizationname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/users/{user}/password": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Users"], - "summary": "Update user password", - "operationId": "update-user-password", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update password request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserPasswordRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/users/{user}/profile": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Update user profile", - "operationId": "update-user-profile", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Updated profile", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserProfileRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/roles": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Get user roles", - "operationId": "get-user-roles", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Assign role to user", - "operationId": "assign-role-to-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update roles request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateRoles" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/status/activate": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Activate user account", - "operationId": "activate-user-account", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/status/suspend": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Users"], - "summary": "Suspend user account", - "operationId": "suspend-user-account", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/workspace/{workspacename}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Get workspace metadata by user and workspace name", - "operationId": "get-workspace-metadata-by-user-and-workspace-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace name", - "name": "workspacename", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Return data instead of HTTP 404 if the workspace is deleted", - "name": "include_deleted", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get workspace build by user, workspace name, and build number", - "operationId": "get-workspace-build-by-user-workspace-name-and-build-number", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace name", - "name": "workspacename", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "number", - "description": "Build number", - "name": "buildnumber", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspace-quota/{user}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Enterprise"], - "summary": "Get workspace quota by user", - "operationId": "get-workspace-quota-by-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceQuota" - } - } - } - } - }, - "/workspaceagents/aws-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Authenticate agent on AWS instance", - "operationId": "authenticate-agent-on-aws-instance", - "parameters": [ - { - "description": "Instance identity token", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.AWSInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/azure-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Authenticate agent on Azure instance", - "operationId": "authenticate-agent-on-azure-instance", - "parameters": [ - { - "description": "Instance identity token", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.AzureInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/google-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Authenticate agent on Google Cloud instance", - "operationId": "authenticate-agent-on-google-cloud-instance", - "parameters": [ - { - "description": "Instance identity token", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.GoogleInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/me/app-health": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Submit workspace agent application health", - "operationId": "submit-workspace-agent-application-health", - "parameters": [ - { - "description": "Application health request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostAppHealthsRequest" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/workspaceagents/me/coordinate": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "It accepts a WebSocket connection to an agent that listens to\nincoming connections and publishes node updates.", - "tags": ["Agents"], - "summary": "Coordinate workspace agent via Tailnet", - "operationId": "coordinate-workspace-agent-via-tailnet", - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspaceagents/me/gitauth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get workspace agent Git auth", - "operationId": "get-workspace-agent-git-auth", - "parameters": [ - { - "type": "string", - "format": "uri", - "description": "Git URL", - "name": "url", - "in": "query", - "required": true - }, - { - "type": "boolean", - "description": "Wait for a new token to be issued", - "name": "listen", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.GitAuthResponse" - } - } - } - } - }, - "/workspaceagents/me/gitsshkey": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get workspace agent Git SSH key", - "operationId": "get-workspace-agent-git-ssh-key", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.GitSSHKey" - } - } - } - } - }, - "/workspaceagents/me/metadata": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get authorized workspace agent metadata", - "operationId": "get-authorized-workspace-agent-metadata", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.Metadata" - } - } - } - } - }, - "/workspaceagents/me/report-lifecycle": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Agents"], - "summary": "Submit workspace agent lifecycle state", - "operationId": "submit-workspace-agent-lifecycle-state", - "parameters": [ - { - "description": "Workspace agent lifecycle request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostLifecycleRequest" - } - } - ], - "responses": { - "204": { - "description": "Success" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceagents/me/report-stats": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Submit workspace agent stats", - "operationId": "submit-workspace-agent-stats", - "parameters": [ - { - "description": "Stats request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.Stats" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.StatsResponse" - } - } - } - } - }, - "/workspaceagents/me/startup": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Submit workspace agent startup", - "operationId": "submit-workspace-agent-startup", - "parameters": [ - { - "description": "Startup request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostStartupRequest" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceagents/{workspaceagent}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get workspace agent by ID", - "operationId": "get-workspace-agent-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgent" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/connection": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get connection info for workspace agent", - "operationId": "get-connection-info-for-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentConnectionInfo" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/coordinate": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Coordinate workspace agent", - "operationId": "coordinate-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspaceagents/{workspaceagent}/listening-ports": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Agents"], - "summary": "Get listening ports for workspace agent", - "operationId": "get-listening-ports-for-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPortsResponse" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/pty": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": ["Agents"], - "summary": "Open PTY to workspace agent", - "operationId": "open-pty-to-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspacebuilds/{workspacebuild}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get workspace build", - "operationId": "get-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/cancel": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Cancel workspace build", - "operationId": "cancel-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get workspace build logs", - "operationId": "get-workspace-build-logs", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get build parameters for workspace build", - "operationId": "get-build-parameters-for-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get workspace resources for workspace build", - "operationId": "get-workspace-resources-for-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/state": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get provisioner state for workspace build", - "operationId": "get-provisioner-state-for-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspaces": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "List workspaces", - "operationId": "list-workspaces", - "parameters": [ - { - "type": "string", - "description": "Filter by owner username", - "name": "owner", - "in": "query" - }, - { - "type": "string", - "description": "Filter by template name", - "name": "template", - "in": "query" - }, - { - "type": "string", - "description": "Filter with partial-match by workspace name", - "name": "name", - "in": "query" - }, - { - "enum": [ - "pending", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleted", - "deleting" - ], - "type": "string", - "description": "Filter by workspace status", - "name": "status", - "in": "query" - }, - { - "enum": ["connected", "connecting", "disconnected", "timeout"], - "type": "string", - "description": "Filter by agent status", - "name": "has_agent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspacesResponse" - } - } - } - } - }, - "/workspaces/{workspace}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Get workspace metadata by ID", - "operationId": "get-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Return data instead of HTTP 404 if the workspace is deleted", - "name": "include_deleted", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace metadata by ID", - "operationId": "update-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Metadata update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/autostart": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace autostart schedule by ID", - "operationId": "update-workspace-autostart-schedule-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Schedule update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/builds": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Get workspace builds by workspace ID", - "operationId": "get-workspace-builds-by-workspace-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - }, - { - "type": "string", - "format": "date-time", - "description": "Since timestamp", - "name": "since", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Builds"], - "summary": "Create workspace build", - "operationId": "create-workspace-build", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Create workspace build request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceBuildRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspaces/{workspace}/extend": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "produces": ["application/json"], - "tags": ["Workspaces"], - "summary": "Extend workspace deadline by ID", - "operationId": "extend-workspace-deadline-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Extend deadline update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PutExtendWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/workspaces/{workspace}/ttl": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": ["application/json"], - "tags": ["Workspaces"], - "summary": "Update workspace TTL by ID", - "operationId": "update-workspace-ttl-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Workspace TTL update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceTTLRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/watch": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": ["text/event-stream"], - "tags": ["Workspaces"], - "summary": "Watch workspace by ID", - "operationId": "watch-workspace-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - } - }, - "definitions": { - "agentsdk.AWSInstanceIdentityToken": { - "type": "object", - "required": ["document", "signature"], - "properties": { - "document": { - "type": "string" - }, - "signature": { - "type": "string" - } - } - }, - "agentsdk.AuthenticateResponse": { - "type": "object", - "properties": { - "session_token": { - "type": "string" - } - } - }, - "agentsdk.AzureInstanceIdentityToken": { - "type": "object", - "required": ["encoding", "signature"], - "properties": { - "encoding": { - "type": "string" - }, - "signature": { - "type": "string" - } - } - }, - "agentsdk.GitAuthResponse": { - "type": "object", - "properties": { - "password": { - "type": "string" - }, - "url": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "agentsdk.GitSSHKey": { - "type": "object", - "properties": { - "private_key": { - "type": "string" - }, - "public_key": { - "type": "string" - } - } - }, - "agentsdk.GoogleInstanceIdentityToken": { - "type": "object", - "required": ["json_web_token"], - "properties": { - "json_web_token": { - "type": "string" - } - } - }, - "agentsdk.Metadata": { - "type": "object", - "properties": { - "apps": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceApp" - } - }, - "derpmap": { - "$ref": "#/definitions/tailcfg.DERPMap" - }, - "directory": { - "type": "string" - }, - "environment_variables": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "git_auth_configs": { - "description": "GitAuthConfigs stores the number of Git configurations\nthe Coder deployment has. If this number is \u003e0, we\nset up special configuration in the workspace.", - "type": "integer" - }, - "motd_file": { - "type": "string" - }, - "shutdown_script": { - "type": "string" - }, - "shutdown_script_timeout": { - "type": "integer" - }, - "startup_script": { - "type": "string" - }, - "startup_script_timeout": { - "type": "integer" - }, - "vscode_port_proxy_uri": { - "type": "string" - } - } - }, - "agentsdk.PostAppHealthsRequest": { - "type": "object", - "properties": { - "healths": { - "description": "Healths is a map of the workspace app name and the health of the app.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.WorkspaceAppHealth" - } - } - } - }, - "agentsdk.PostLifecycleRequest": { - "type": "object", - "properties": { - "state": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" - } - } - }, - "agentsdk.PostStartupRequest": { - "type": "object", - "properties": { - "expanded_directory": { - "type": "string" - }, - "version": { - "type": "string" - } - } - }, - "agentsdk.Stats": { - "type": "object", - "properties": { - "connection_count": { - "description": "ConnectionCount is the number of connections received by an agent.", - "type": "integer" - }, - "connection_median_latency_ms": { - "description": "ConnectionMedianLatencyMS is the median latency of all connections in milliseconds.", - "type": "number" - }, - "connections_by_proto": { - "description": "ConnectionsByProto is a count of connections by protocol.", - "type": "object", - "additionalProperties": { - "type": "integer" - } - }, - "rx_bytes": { - "description": "RxBytes is the number of received bytes.", - "type": "integer" - }, - "rx_packets": { - "description": "RxPackets is the number of received packets.", - "type": "integer" - }, - "session_count_jetbrains": { - "description": "SessionCountJetBrains is the number of connections received by an agent\nthat are from our JetBrains extension.", - "type": "integer" - }, - "session_count_reconnecting_pty": { - "description": "SessionCountReconnectingPTY is the number of connections received by an agent\nthat are from the reconnecting web terminal.", - "type": "integer" - }, - "session_count_ssh": { - "description": "SessionCountSSH is the number of connections received by an agent\nthat are normal, non-tagged SSH sessions.", - "type": "integer" - }, - "session_count_vscode": { - "description": "SessionCountVSCode is the number of connections received by an agent\nthat are from our VS Code extension.", - "type": "integer" - }, - "tx_bytes": { - "description": "TxBytes is the number of transmitted bytes.", - "type": "integer" - }, - "tx_packets": { - "description": "TxPackets is the number of transmitted bytes.", - "type": "integer" - } - } - }, - "agentsdk.StatsResponse": { - "type": "object", - "properties": { - "report_interval": { - "description": "ReportInterval is the duration after which the agent should send stats\nagain.", - "type": "integer" - } - } - }, - "clibase.Annotations": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "clibase.Group": { - "type": "object", - "properties": { - "children": { - "type": "array", - "items": { - "$ref": "#/definitions/clibase.Group" - } - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "parent": { - "$ref": "#/definitions/clibase.Group" - } - } - }, - "clibase.HostPort": { - "type": "object", - "properties": { - "host": { - "type": "string" - }, - "port": { - "type": "string" - } - } - }, - "clibase.Option": { - "type": "object", - "properties": { - "annotations": { - "description": "Annotations enable extensions to clibase higher up in the stack. It's useful for\nhelp formatting and documentation generation.", - "allOf": [ - { - "$ref": "#/definitions/clibase.Annotations" - } - ] - }, - "default": { - "description": "Default is parsed into Value if set.", - "type": "string" - }, - "description": { - "type": "string" - }, - "env": { - "description": "Env is the environment variable used to configure this option. If unset,\nenvironment configuring is disabled.", - "type": "string" - }, - "flag": { - "description": "Flag is the long name of the flag used to configure this option. If unset,\nflag configuring is disabled.", - "type": "string" - }, - "flag_shorthand": { - "description": "FlagShorthand is the one-character shorthand for the flag. If unset, no\nshorthand is used.", - "type": "string" - }, - "group": { - "description": "Group is a group hierarchy that helps organize this option in help, configs\nand other documentation.", - "allOf": [ - { - "$ref": "#/definitions/clibase.Group" - } - ] - }, - "hidden": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "use_instead": { - "description": "UseInstead is a list of options that should be used instead of this one.\nThe field is used to generate a deprecation warning.", - "type": "array", - "items": { - "$ref": "#/definitions/clibase.Option" - } - }, - "value": { - "description": "Value includes the types listed in values.go." - }, - "yaml": { - "description": "YAML is the YAML key used to configure this option. If unset, YAML\nconfiguring is disabled.", - "type": "string" - } - } - }, - "clibase.Struct-array_codersdk_GitAuthConfig": { - "type": "object", - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.GitAuthConfig" - } - } - } - }, - "clibase.Struct-array_codersdk_LinkConfig": { - "type": "object", - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.LinkConfig" - } - } - } - }, - "clibase.URL": { - "type": "object", - "properties": { - "forceQuery": { - "description": "append a query ('?') even if RawQuery is empty", - "type": "boolean" - }, - "fragment": { - "description": "fragment for references, without '#'", - "type": "string" - }, - "host": { - "description": "host or host:port", - "type": "string" - }, - "omitHost": { - "description": "do not emit empty host (authority)", - "type": "boolean" - }, - "opaque": { - "description": "encoded opaque data", - "type": "string" - }, - "path": { - "description": "path (relative paths may omit leading slash)", - "type": "string" - }, - "rawFragment": { - "description": "encoded fragment hint (see EscapedFragment method)", - "type": "string" - }, - "rawPath": { - "description": "encoded path hint (see EscapedPath method)", - "type": "string" - }, - "rawQuery": { - "description": "encoded query values, without '?'", - "type": "string" - }, - "scheme": { - "type": "string" - }, - "user": { - "description": "username and password information", - "allOf": [ - { - "$ref": "#/definitions/url.Userinfo" - } - ] - } - } - }, - "coderd.SCIMUser": { - "type": "object", - "properties": { - "active": { - "type": "boolean" - }, - "emails": { - "type": "array", - "items": { - "type": "object", - "properties": { - "display": { - "type": "string" - }, - "primary": { - "type": "boolean" - }, - "type": { - "type": "string" - }, - "value": { - "type": "string", - "format": "email" - } - } - } - }, - "groups": { - "type": "array", - "items": {} - }, - "id": { - "type": "string" - }, - "meta": { - "type": "object", - "properties": { - "resourceType": { - "type": "string" - } - } - }, - "name": { - "type": "object", - "properties": { - "familyName": { - "type": "string" - }, - "givenName": { - "type": "string" - } - } - }, - "schemas": { - "type": "array", - "items": { - "type": "string" - } - }, - "userName": { - "type": "string" - } - } - }, - "coderd.cspViolation": { - "type": "object", - "properties": { - "csp-report": { - "type": "object", - "additionalProperties": true - } - } - }, - "codersdk.APIKey": { - "type": "object", - "required": [ - "created_at", - "expires_at", - "id", - "last_used", - "lifetime_seconds", - "login_type", - "scope", - "token_name", - "updated_at", - "user_id" - ], - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "expires_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string" - }, - "last_used": { - "type": "string", - "format": "date-time" - }, - "lifetime_seconds": { - "type": "integer" - }, - "login_type": { - "enum": ["password", "github", "oidc", "token"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.LoginType" - } - ] - }, - "scope": { - "enum": ["all", "application_connect"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.APIKeyScope" - } - ] - }, - "token_name": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.APIKeyScope": { - "type": "string", - "enum": ["all", "application_connect"], - "x-enum-varnames": ["APIKeyScopeAll", "APIKeyScopeApplicationConnect"] - }, - "codersdk.AddLicenseRequest": { - "type": "object", - "required": ["license"], - "properties": { - "license": { - "type": "string" - } - } - }, - "codersdk.AppHostResponse": { - "type": "object", - "properties": { - "host": { - "description": "Host is the externally accessible URL for the Coder instance.", - "type": "string" - } - } - }, - "codersdk.AppearanceConfig": { - "type": "object", - "properties": { - "logo_url": { - "type": "string" - }, - "service_banner": { - "$ref": "#/definitions/codersdk.ServiceBannerConfig" - }, - "support_links": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.LinkConfig" - } - } - } - }, - "codersdk.AssignableRoles": { - "type": "object", - "properties": { - "assignable": { - "type": "boolean" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.AuditAction": { - "type": "string", - "enum": ["create", "write", "delete", "start", "stop", "login", "logout"], - "x-enum-varnames": [ - "AuditActionCreate", - "AuditActionWrite", - "AuditActionDelete", - "AuditActionStart", - "AuditActionStop", - "AuditActionLogin", - "AuditActionLogout" - ] - }, - "codersdk.AuditDiff": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.AuditDiffField" - } - }, - "codersdk.AuditDiffField": { - "type": "object", - "properties": { - "new": {}, - "old": {}, - "secret": { - "type": "boolean" - } - } - }, - "codersdk.AuditLog": { - "type": "object", - "properties": { - "action": { - "$ref": "#/definitions/codersdk.AuditAction" - }, - "additional_fields": { - "type": "array", - "items": { - "type": "integer" - } - }, - "description": { - "type": "string" - }, - "diff": { - "$ref": "#/definitions/codersdk.AuditDiff" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "ip": { - "type": "string" - }, - "is_deleted": { - "type": "boolean" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "request_id": { - "type": "string", - "format": "uuid" - }, - "resource_icon": { - "type": "string" - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "resource_link": { - "type": "string" - }, - "resource_target": { - "description": "ResourceTarget is the name of the resource.", - "type": "string" - }, - "resource_type": { - "$ref": "#/definitions/codersdk.ResourceType" - }, - "status_code": { - "type": "integer" - }, - "time": { - "type": "string", - "format": "date-time" - }, - "user": { - "$ref": "#/definitions/codersdk.User" - }, - "user_agent": { - "type": "string" - } - } - }, - "codersdk.AuditLogResponse": { - "type": "object", - "properties": { - "audit_logs": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AuditLog" - } - }, - "count": { - "type": "integer" - } - } - }, - "codersdk.AuthMethod": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } - }, - "codersdk.AuthMethods": { - "type": "object", - "properties": { - "github": { - "$ref": "#/definitions/codersdk.AuthMethod" - }, - "oidc": { - "$ref": "#/definitions/codersdk.OIDCAuthMethod" - }, - "password": { - "$ref": "#/definitions/codersdk.AuthMethod" - } - } - }, - "codersdk.AuthorizationCheck": { - "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", - "type": "object", - "properties": { - "action": { - "type": "string", - "enum": ["create", "read", "update", "delete"] - }, - "object": { - "description": "Object can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product.\nWhen defining an object, use the most specific language when possible to\nproduce the smallest set. Meaning to set as many fields on 'Object' as\nyou can. Example, if you want to check if you can update all workspaces\nowned by 'me', try to also add an 'OrganizationID' to the settings.\nOmitting the 'OrganizationID' could produce the incorrect value, as\nworkspaces have both `user` and `organization` owners.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.AuthorizationObject" - } - ] - } - } - }, - "codersdk.AuthorizationObject": { - "description": "AuthorizationObject can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.", - "type": "object", - "properties": { - "organization_id": { - "description": "OrganizationID (optional) adds the set constraint to all resources owned by a given organization.", - "type": "string" - }, - "owner_id": { - "description": "OwnerID (optional) adds the set constraint to all resources owned by a given user.", - "type": "string" - }, - "resource_id": { - "description": "ResourceID (optional) reduces the set to a singular resource. This assigns\na resource ID to the resource type, eg: a single workspace.\nThe rbac library will not fetch the resource from the database, so if you\nare using this option, you should also set the owner ID and organization ID\nif possible. Be as specific as possible using all the fields relevant.", - "type": "string" - }, - "resource_type": { - "description": "ResourceType is the name of the resource.\n`./coderd/rbac/object.go` has the list of valid resource types.", - "type": "string" - } - } - }, - "codersdk.AuthorizationRequest": { - "type": "object", - "properties": { - "checks": { - "description": "Checks is a map keyed with an arbitrary string to a permission check.\nThe key can be any string that is helpful to the caller, and allows\nmultiple permission checks to be run in a single request.\nThe key ensures that each permission check has the same key in the\nresponse.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.AuthorizationCheck" - } - } - } - }, - "codersdk.AuthorizationResponse": { - "type": "object", - "additionalProperties": { - "type": "boolean" - } - }, - "codersdk.BuildInfoResponse": { - "type": "object", - "properties": { - "external_url": { - "description": "ExternalURL references the current Coder version.\nFor production builds, this will link directly to a release. For development builds, this will link to a commit.", - "type": "string" - }, - "version": { - "description": "Version returns the semantic version of the build.", - "type": "string" - } - } - }, - "codersdk.BuildReason": { - "type": "string", - "enum": ["initiator", "autostart", "autostop"], - "x-enum-varnames": [ - "BuildReasonInitiator", - "BuildReasonAutostart", - "BuildReasonAutostop" - ] - }, - "codersdk.CreateFirstUserRequest": { - "type": "object", - "required": ["email", "password", "username"], - "properties": { - "email": { - "type": "string" - }, - "password": { - "type": "string" - }, - "trial": { - "type": "boolean" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.CreateFirstUserResponse": { - "type": "object", - "properties": { - "organization_id": { - "type": "string", - "format": "uuid" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.CreateGroupRequest": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "name": { - "type": "string" - }, - "quota_allowance": { - "type": "integer" - } - } - }, - "codersdk.CreateOrganizationRequest": { - "type": "object", - "required": ["name"], - "properties": { - "name": { - "type": "string" - } - } - }, - "codersdk.CreateParameterRequest": { - "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", - "type": "object", - "required": [ - "destination_scheme", - "name", - "source_scheme", - "source_value" - ], - "properties": { - "copy_from_parameter": { - "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", - "type": "string", - "format": "uuid" - }, - "destination_scheme": { - "enum": ["none", "environment_variable", "provisioner_variable"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterDestinationScheme" - } - ] - }, - "name": { - "type": "string" - }, - "source_scheme": { - "enum": ["none", "data"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterSourceScheme" - } - ] - }, - "source_value": { - "type": "string" - } - } - }, - "codersdk.CreateTemplateRequest": { - "type": "object", - "required": ["name", "template_version_id"], - "properties": { - "allow_user_cancel_workspace_jobs": { - "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", - "type": "boolean" - }, - "default_ttl_ms": { - "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", - "type": "integer" - }, - "description": { - "description": "Description is a description of what the template contains. It must be\nless than 128 bytes.", - "type": "string" - }, - "display_name": { - "description": "DisplayName is the displayed name of the template.", - "type": "string" - }, - "icon": { - "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", - "type": "string" - }, - "max_ttl_ms": { - "description": "MaxTTLMillis allows optionally specifying the max lifetime for\nworkspaces created from this template.", - "type": "integer" - }, - "name": { - "description": "Name is the name of the template.", - "type": "string" - }, - "parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "template_version_id": { - "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.CreateTemplateVersionDryRunRequest": { - "type": "object", - "properties": { - "parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "user_variable_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.VariableValue" - } - }, - "workspace_name": { - "type": "string" - } - } - }, - "codersdk.CreateTemplateVersionRequest": { - "type": "object", - "required": ["provisioner", "storage_method"], - "properties": { - "example_id": { - "type": "string" - }, - "file_id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "parameter_values": { - "description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "provisioner": { - "type": "string", - "enum": ["terraform", "echo"] - }, - "storage_method": { - "enum": ["file"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerStorageMethod" - } - ] - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "template_id": { - "description": "TemplateID optionally associates a version with a template.", - "type": "string", - "format": "uuid" - }, - "user_variable_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.VariableValue" - } - } - } - }, - "codersdk.CreateTestAuditLogRequest": { - "type": "object", - "properties": { - "action": { - "enum": ["create", "write", "delete", "start", "stop"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.AuditAction" - } - ] - }, - "additional_fields": { - "type": "array", - "items": { - "type": "integer" - } - }, - "build_reason": { - "enum": ["autostart", "autostop", "initiator"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.BuildReason" - } - ] - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "resource_type": { - "enum": [ - "template", - "template_version", - "user", - "workspace", - "workspace_build", - "git_ssh_key", - "auditable_group" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ResourceType" - } - ] - }, - "time": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.CreateTokenRequest": { - "type": "object", - "properties": { - "lifetime": { - "type": "integer" - }, - "scope": { - "enum": ["all", "application_connect"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.APIKeyScope" - } - ] - }, - "token_name": { - "type": "string" - } - } - }, - "codersdk.CreateUserRequest": { - "type": "object", - "required": ["email", "organization_id", "password", "username"], - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "password": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.CreateWorkspaceBuildRequest": { - "type": "object", - "required": ["transition"], - "properties": { - "dry_run": { - "type": "boolean" - }, - "orphan": { - "description": "Orphan may be set for the Destroy transition.", - "type": "boolean" - }, - "parameter_values": { - "description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "state": { - "type": "array", - "items": { - "type": "integer" - } - }, - "template_version_id": { - "type": "string", - "format": "uuid" - }, - "transition": { - "enum": ["create", "start", "stop", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - } - } - }, - "codersdk.CreateWorkspaceRequest": { - "type": "object", - "required": ["name", "template_id"], - "properties": { - "autostart_schedule": { - "type": "string" - }, - "name": { - "type": "string" - }, - "parameter_values": { - "description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "template_id": { - "type": "string", - "format": "uuid" - }, - "ttl_ms": { - "type": "integer" - } - } - }, - "codersdk.DAUEntry": { - "type": "object", - "properties": { - "amount": { - "type": "integer" - }, - "date": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.DERP": { - "type": "object", - "properties": { - "config": { - "$ref": "#/definitions/codersdk.DERPConfig" - }, - "server": { - "$ref": "#/definitions/codersdk.DERPServerConfig" - } - } - }, - "codersdk.DERPConfig": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "url": { - "type": "string" - } - } - }, - "codersdk.DERPRegion": { - "type": "object", - "properties": { - "latency_ms": { - "type": "number" - }, - "preferred": { - "type": "boolean" - } - } - }, - "codersdk.DERPServerConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - }, - "region_code": { - "type": "string" - }, - "region_id": { - "type": "integer" - }, - "region_name": { - "type": "string" - }, - "relay_url": { - "$ref": "#/definitions/clibase.URL" - }, - "stun_addresses": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.DangerousConfig": { - "type": "object", - "properties": { - "allow_path_app_sharing": { - "type": "boolean" - }, - "allow_path_app_site_owner_access": { - "type": "boolean" - } - } - }, - "codersdk.DeploymentConfig": { - "type": "object", - "properties": { - "config": { - "$ref": "#/definitions/codersdk.DeploymentValues" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/clibase.Option" - } - } - } - }, - "codersdk.DeploymentDAUsResponse": { - "type": "object", - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.DAUEntry" - } - } - } - }, - "codersdk.DeploymentStats": { - "type": "object", - "properties": { - "aggregated_from": { - "description": "AggregatedFrom is the time in which stats are aggregated from.\nThis might be back in time a specific duration or interval.", - "type": "string", - "format": "date-time" - }, - "collected_at": { - "description": "CollectedAt is the time in which stats are collected at.", - "type": "string", - "format": "date-time" - }, - "next_update_at": { - "description": "NextUpdateAt is the time when the next batch of stats will\nbe updated.", - "type": "string", - "format": "date-time" - }, - "session_count": { - "$ref": "#/definitions/codersdk.SessionCountDeploymentStats" - }, - "workspaces": { - "$ref": "#/definitions/codersdk.WorkspaceDeploymentStats" - } - } - }, - "codersdk.DeploymentValues": { - "type": "object", - "properties": { - "access_url": { - "$ref": "#/definitions/clibase.URL" - }, - "address": { - "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", - "allOf": [ - { - "$ref": "#/definitions/clibase.HostPort" - } - ] - }, - "agent_fallback_troubleshooting_url": { - "$ref": "#/definitions/clibase.URL" - }, - "agent_stat_refresh_interval": { - "type": "integer" - }, - "audit_logging": { - "type": "boolean" - }, - "autobuild_poll_interval": { - "type": "integer" - }, - "browser_only": { - "type": "boolean" - }, - "cache_directory": { - "type": "string" - }, - "config": { - "type": "string" - }, - "config_ssh": { - "$ref": "#/definitions/codersdk.SSHConfig" - }, - "dangerous": { - "$ref": "#/definitions/codersdk.DangerousConfig" - }, - "derp": { - "$ref": "#/definitions/codersdk.DERP" - }, - "disable_password_auth": { - "type": "boolean" - }, - "disable_path_apps": { - "type": "boolean" - }, - "disable_session_expiry_refresh": { - "type": "boolean" - }, - "experiments": { - "type": "array", - "items": { - "type": "string" - } - }, - "git_auth": { - "$ref": "#/definitions/clibase.Struct-array_codersdk_GitAuthConfig" - }, - "http_address": { - "description": "HTTPAddress is a string because it may be set to zero to disable.", - "type": "string" - }, - "in_memory_database": { - "type": "boolean" - }, - "logging": { - "$ref": "#/definitions/codersdk.LoggingConfig" - }, - "max_session_expiry": { - "type": "integer" - }, - "max_token_lifetime": { - "type": "integer" - }, - "metrics_cache_refresh_interval": { - "type": "integer" - }, - "oauth2": { - "$ref": "#/definitions/codersdk.OAuth2Config" - }, - "oidc": { - "$ref": "#/definitions/codersdk.OIDCConfig" - }, - "pg_connection_url": { - "type": "string" - }, - "pprof": { - "$ref": "#/definitions/codersdk.PprofConfig" - }, - "prometheus": { - "$ref": "#/definitions/codersdk.PrometheusConfig" - }, - "provisioner": { - "$ref": "#/definitions/codersdk.ProvisionerConfig" - }, - "proxy_trusted_headers": { - "type": "array", - "items": { - "type": "string" - } - }, - "proxy_trusted_origins": { - "type": "array", - "items": { - "type": "string" - } - }, - "rate_limit": { - "$ref": "#/definitions/codersdk.RateLimitConfig" - }, - "redirect_to_access_url": { - "type": "boolean" - }, - "scim_api_key": { - "type": "string" - }, - "secure_auth_cookie": { - "type": "boolean" - }, - "ssh_keygen_algorithm": { - "type": "string" - }, - "strict_transport_security": { - "type": "integer" - }, - "strict_transport_security_options": { - "type": "array", - "items": { - "type": "string" - } - }, - "support": { - "$ref": "#/definitions/codersdk.SupportConfig" - }, - "swagger": { - "$ref": "#/definitions/codersdk.SwaggerConfig" - }, - "telemetry": { - "$ref": "#/definitions/codersdk.TelemetryConfig" - }, - "tls": { - "$ref": "#/definitions/codersdk.TLSConfig" - }, - "trace": { - "$ref": "#/definitions/codersdk.TraceConfig" - }, - "update_check": { - "type": "boolean" - }, - "verbose": { - "type": "boolean" - }, - "wildcard_access_url": { - "$ref": "#/definitions/clibase.URL" - }, - "write_config": { - "type": "boolean" - } - } - }, - "codersdk.Entitlement": { - "type": "string", - "enum": ["entitled", "grace_period", "not_entitled"], - "x-enum-varnames": [ - "EntitlementEntitled", - "EntitlementGracePeriod", - "EntitlementNotEntitled" - ] - }, - "codersdk.Entitlements": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "type": "string" - } - }, - "features": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.Feature" - } - }, - "has_license": { - "type": "boolean" - }, - "require_telemetry": { - "type": "boolean" - }, - "trial": { - "type": "boolean" - }, - "warnings": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.Experiment": { - "type": "string", - "enum": ["authz_querier", "template_editor"], - "x-enum-varnames": ["ExperimentAuthzQuerier", "ExperimentTemplateEditor"] - }, - "codersdk.Feature": { - "type": "object", - "properties": { - "actual": { - "type": "integer" - }, - "enabled": { - "type": "boolean" - }, - "entitlement": { - "$ref": "#/definitions/codersdk.Entitlement" - }, - "limit": { - "type": "integer" - } - } - }, - "codersdk.GenerateAPIKeyResponse": { - "type": "object", - "properties": { - "key": { - "type": "string" - } - } - }, - "codersdk.GetUsersResponse": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "users": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "codersdk.GitAuthConfig": { - "type": "object", - "properties": { - "auth_url": { - "type": "string" + "swagger": "2.0", + "info": { + "description": "Coderd is the service created by running coder server. It is a thin API that connects workspaces, provisioners and users. coderd stores its state in Postgres and is the only service that communicates with Postgres.", + "title": "Coder API", + "termsOfService": "https://coder.com/legal/terms-of-service", + "contact": { + "name": "API Support", + "url": "https://coder.com", + "email": "support@coder.com" }, - "client_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "no_refresh": { - "type": "boolean" - }, - "regex": { - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - }, - "token_url": { - "type": "string" - }, - "type": { - "type": "string" - }, - "validate_url": { - "type": "string" - } - } - }, - "codersdk.GitProvider": { - "type": "string", - "enum": ["azure-devops", "github", "gitlab", "bitbucket"], - "x-enum-varnames": [ - "GitProviderAzureDevops", - "GitProviderGitHub", - "GitProviderGitLab", - "GitProviderBitBucket" - ] - }, - "codersdk.GitSSHKey": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "public_key": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.Group": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.User" - } - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "quota_allowance": { - "type": "integer" - } - } - }, - "codersdk.Healthcheck": { - "type": "object", - "properties": { - "interval": { - "description": "Interval specifies the seconds between each health check.", - "type": "integer" - }, - "threshold": { - "description": "Threshold specifies the number of consecutive failed health checks before returning \"unhealthy\".", - "type": "integer" - }, - "url": { - "description": "URL specifies the endpoint to check for the app health.", - "type": "string" - } - } - }, - "codersdk.JobErrorCode": { - "type": "string", - "enum": ["MISSING_TEMPLATE_PARAMETER", "REQUIRED_TEMPLATE_VARIABLES"], - "x-enum-varnames": [ - "MissingTemplateParameter", - "RequiredTemplateVariables" - ] - }, - "codersdk.License": { - "type": "object", - "properties": { - "claims": { - "description": "Claims are the JWT claims asserted by the license. Here we use\na generic string map to ensure that all data from the server is\nparsed verbatim, not just the fields this version of Coder\nunderstands.", - "type": "object", - "additionalProperties": true - }, - "id": { - "type": "integer" - }, - "uploaded_at": { - "type": "string", - "format": "date-time" - }, - "uuid": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.LinkConfig": { - "type": "object", - "properties": { - "icon": { - "type": "string" - }, - "name": { - "type": "string" - }, - "target": { - "type": "string" - } - } - }, - "codersdk.LogLevel": { - "type": "string", - "enum": ["trace", "debug", "info", "warn", "error"], - "x-enum-varnames": [ - "LogLevelTrace", - "LogLevelDebug", - "LogLevelInfo", - "LogLevelWarn", - "LogLevelError" - ] - }, - "codersdk.LogSource": { - "type": "string", - "enum": ["provisioner_daemon", "provisioner"], - "x-enum-varnames": ["LogSourceProvisionerDaemon", "LogSourceProvisioner"] - }, - "codersdk.LoggingConfig": { - "type": "object", - "properties": { - "human": { - "type": "string" - }, - "json": { - "type": "string" - }, - "stackdriver": { - "type": "string" - } - } - }, - "codersdk.LoginType": { - "type": "string", - "enum": ["password", "github", "oidc", "token"], - "x-enum-varnames": [ - "LoginTypePassword", - "LoginTypeGithub", - "LoginTypeOIDC", - "LoginTypeToken" - ] - }, - "codersdk.LoginWithPasswordRequest": { - "type": "object", - "required": ["email", "password"], - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string" - } - } - }, - "codersdk.LoginWithPasswordResponse": { - "type": "object", - "required": ["session_token"], - "properties": { - "session_token": { - "type": "string" - } - } - }, - "codersdk.OAuth2Config": { - "type": "object", - "properties": { - "github": { - "$ref": "#/definitions/codersdk.OAuth2GithubConfig" - } - } - }, - "codersdk.OAuth2GithubConfig": { - "type": "object", - "properties": { - "allow_everyone": { - "type": "boolean" - }, - "allow_signups": { - "type": "boolean" - }, - "allowed_orgs": { - "type": "array", - "items": { - "type": "string" - } - }, - "allowed_teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - }, - "enterprise_base_url": { - "type": "string" - } - } - }, - "codersdk.OIDCAuthMethod": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "iconUrl": { - "type": "string" - }, - "signInText": { - "type": "string" - } - } - }, - "codersdk.OIDCConfig": { - "type": "object", - "properties": { - "allow_signups": { - "type": "boolean" - }, - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - }, - "email_domain": { - "type": "array", - "items": { - "type": "string" - } - }, - "groups_field": { - "type": "string" - }, - "icon_url": { - "$ref": "#/definitions/clibase.URL" - }, - "ignore_email_verified": { - "type": "boolean" - }, - "issuer_url": { - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - }, - "sign_in_text": { - "type": "string" - }, - "username_field": { - "type": "string" - } - } - }, - "codersdk.Organization": { - "type": "object", - "required": ["created_at", "id", "name", "updated_at"], - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.OrganizationMember": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.Parameter": { - "description": "Parameter represents a set value for the scope.", - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "destination_scheme": { - "enum": ["none", "environment_variable", "provisioner_variable"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterDestinationScheme" - } - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "scope": { - "enum": ["template", "workspace", "import_job"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterScope" - } - ] - }, - "scope_id": { - "type": "string", - "format": "uuid" - }, - "source_scheme": { - "enum": ["none", "data"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterSourceScheme" - } - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.ParameterDestinationScheme": { - "type": "string", - "enum": ["none", "environment_variable", "provisioner_variable"], - "x-enum-varnames": [ - "ParameterDestinationSchemeNone", - "ParameterDestinationSchemeEnvironmentVariable", - "ParameterDestinationSchemeProvisionerVariable" - ] - }, - "codersdk.ParameterSchema": { - "type": "object", - "properties": { - "allow_override_destination": { - "type": "boolean" - }, - "allow_override_source": { - "type": "boolean" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "default_destination_scheme": { - "enum": ["none", "environment_variable", "provisioner_variable"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterDestinationScheme" + "license": { + "name": "AGPL-3.0", + "url": "https://github.com/coder/coder/blob/main/LICENSE" + }, + "version": "2.0" + }, + "basePath": "/api/v2", + "paths": { + "/": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "API root handler", + "operationId": "api-root-handler", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/appearance": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get appearance", + "operationId": "get-appearance", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AppearanceConfig" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Update appearance", + "operationId": "update-appearance", + "parameters": [ + { + "description": "Update appearance request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" + } + } + } + } + }, + "/applications/auth-redirect": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Applications" + ], + "summary": "Redirect to URI with encrypted API key", + "operationId": "redirect-to-uri-with-encrypted-api-key", + "parameters": [ + { + "type": "string", + "description": "Redirect destination", + "name": "redirect_uri", + "in": "query" + } + ], + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/applications/host": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Applications" + ], + "summary": "Get applications host", + "operationId": "get-applications-host", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AppHostResponse" + } + } + } + } + }, + "/audit": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Audit" + ], + "summary": "Get audit logs", + "operationId": "get-audit-logs", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuditLogResponse" + } + } + } + } + }, + "/audit/testgenerate": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Audit" + ], + "summary": "Generate fake audit log", + "operationId": "generate-fake-audit-log", + "parameters": [ + { + "description": "Audit log request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/authcheck": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authorization" + ], + "summary": "Check authorization", + "operationId": "check-authorization", + "parameters": [ + { + "description": "Authorization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AuthorizationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthorizationResponse" + } + } + } + } + }, + "/buildinfo": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Build info", + "operationId": "build-info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.BuildInfoResponse" + } + } + } + } + }, + "/csp/reports": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Report CSP violations", + "operationId": "report-csp-violations", + "parameters": [ + { + "description": "Violation report", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.cspViolation" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/debug/coordinator": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "text/html" + ], + "tags": [ + "Debug" + ], + "summary": "Debug Info Wireguard Coordinator", + "operationId": "debug-info-wireguard-coordinator", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/deployment/config": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Get deployment config", + "operationId": "get-deployment-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentConfig" + } + } + } + } + }, + "/deployment/ssh": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "SSH Config", + "operationId": "ssh-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.SSHConfigResponse" + } + } + } + } + }, + "/deployment/stats": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Get deployment stats", + "operationId": "get-deployment-stats", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentStats" + } + } + } + } + }, + "/entitlements": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get entitlements", + "operationId": "get-entitlements", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Entitlements" + } + } + } + } + }, + "/experiments": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Get experiments", + "operationId": "get-experiments", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Experiment" + } + } + } + } + } + }, + "/files": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Swagger notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", + "consumes": [ + "application/x-tar" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Files" + ], + "summary": "Upload file", + "operationId": "upload-file", + "parameters": [ + { + "type": "string", + "default": "application/x-tar", + "description": "Content-Type must be `application/x-tar`", + "name": "Content-Type", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "File to be uploaded", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.UploadResponse" + } + } + } + } + }, + "/files/{fileID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Files" + ], + "summary": "Get file by ID", + "operationId": "get-file-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "File ID", + "name": "fileID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/groups": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get groups", + "operationId": "get-groups", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + } + }, + "/groups/{group}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get group by name", + "operationId": "get-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Delete group by name", + "operationId": "delete-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Update group by name", + "operationId": "update-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/insights/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Insights" + ], + "summary": "Get deployment DAUs", + "operationId": "get-deployment-daus", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentDAUsResponse" + } + } + } + } + }, + "/licenses": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get licenses", + "operationId": "get-licenses", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.License" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Organizations" + ], + "summary": "Add new license", + "operationId": "add-new-license", + "parameters": [ + { + "description": "Add license request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AddLicenseRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.License" + } + } + } + } + }, + "/licenses/{id}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Delete license", + "operationId": "delete-license", + "parameters": [ + { + "type": "string", + "format": "number", + "description": "License ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/organizations": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Organizations" + ], + "summary": "Create organization", + "operationId": "create-organization", + "parameters": [ + { + "description": "Create organization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateOrganizationRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{organization}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Organizations" + ], + "summary": "Get organization by ID", + "operationId": "get-organization-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{organization}/groups": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get groups by organization", + "operationId": "get-groups-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create group for organization", + "operationId": "create-group-for-organization", + "parameters": [ + { + "description": "Create group request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateGroupRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/organizations/{organization}/groups/{groupName}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get group by organization and group name", + "operationId": "get-group-by-organization-and-group-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group name", + "name": "groupName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/organizations/{organization}/members/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Members" + ], + "summary": "Get member roles by organization", + "operationId": "get-member-roles-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, + "/organizations/{organization}/members/{user}/roles": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Members" + ], + "summary": "Assign role to organization member", + "operationId": "assign-role-to-organization-member", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.OrganizationMember" + } + } + } + } + }, + "/organizations/{organization}/members/{user}/workspaces": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Create user workspace by organization", + "operationId": "create-user-workspace-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Username, UUID, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create workspace request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/organizations/{organization}/provisionerdaemons": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get provisioner daemons", + "operationId": "get-provisioner-daemons", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerDaemon" + } + } + } + } + } + }, + "/organizations/{organization}/provisionerdaemons/serve": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Enterprise" + ], + "summary": "Serve provisioner daemon", + "operationId": "serve-provisioner-daemon", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/organizations/{organization}/templates": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get templates by organization", + "operationId": "get-templates-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create template by organization", + "operationId": "create-template-by-organization", + "parameters": [ + { + "description": "Request body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/examples": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template examples by organization", + "operationId": "get-template-examples-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateExample" + } + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get templates by organization and template name", + "operationId": "get-templates-by-organization-and-template-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version by organization, template, and name", + "operationId": "get-template-version-by-organization-template-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get previous template version by organization, template, and name", + "operationId": "get-previous-template-version-by-organization-template-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templateversions": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create template version by organization", + "operationId": "create-template-version-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Create template version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/parameters/{scope}/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Parameters" + ], + "summary": "Get parameters", + "operationId": "get-parameters", + "parameters": [ + { + "enum": [ + "template", + "workspace", + "import_job" + ], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Parameter" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Parameters" + ], + "summary": "Create parameter", + "operationId": "create-parameter", + "parameters": [ + { + "description": "Parameter request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + { + "enum": [ + "template", + "workspace", + "import_job" + ], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Parameter" + } + } + } + } + }, + "/parameters/{scope}/{id}/{name}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Parameters" + ], + "summary": "Delete parameter", + "operationId": "delete-parameter", + "parameters": [ + { + "enum": [ + "template", + "workspace", + "import_job" + ], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/replicas": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get active replicas", + "operationId": "get-active-replicas", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Replica" + } + } + } + } + } + }, + "/scim/v2/Users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/scim+json" + ], + "tags": [ + "Enterprise" + ], + "summary": "SCIM 2.0: Get users", + "operationId": "scim-get-users", + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "SCIM 2.0: Create new user", + "operationId": "scim-create-new-user", + "parameters": [ + { + "description": "New user", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + } + } + }, + "/scim/v2/Users/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/scim+json" + ], + "tags": [ + "Enterprise" + ], + "summary": "SCIM 2.0: Get user by ID", + "operationId": "scim-get-user-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "404": { + "description": "Not Found" + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/scim+json" + ], + "tags": [ + "Enterprise" + ], + "summary": "SCIM 2.0: Update user account", + "operationId": "scim-update-user-status", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Update user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/templates/{template}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template metadata by ID", + "operationId": "get-template-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Delete template by ID", + "operationId": "delete-template-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Update template metadata by ID", + "operationId": "update-template-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/templates/{template}/acl": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get template ACLs", + "operationId": "get-template-acls", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateUser" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Update template ACL", + "operationId": "update-template-acl", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "description": "Update template request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateTemplateACL" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template DAUs by ID", + "operationId": "get-template-daus-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateDAUsResponse" + } + } + } + } + }, + "/templates/{template}/versions": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "List template versions by template ID", + "operationId": "list-template-versions-by-template-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Update active template version by template ID", + "operationId": "update-active-template-version-by-template-id", + "parameters": [ + { + "description": "Modified template version", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateActiveTemplateVersion" + } + }, + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/versions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version by template ID and name", + "operationId": "get-template-version-by-template-id-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + } + }, + "/templateversions/{templateversion}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version by ID", + "operationId": "get-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/templateversions/{templateversion}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Cancel template version by ID", + "operationId": "cancel-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Create template version dry-run", + "operationId": "create-template-version-dry-run", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "description": "Dry-run request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version dry-run by job ID", + "operationId": "get-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Cancel template version dry-run by job ID", + "operationId": "cancel-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version dry-run logs by job ID", + "operationId": "get-template-version-dry-run-logs-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template version dry-run resources by job ID", + "operationId": "get-template-version-dry-run-resources-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/templateversions/{templateversion}/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get git auth by template version", + "operationId": "get-git-auth-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionGitAuth" + } + } + } + } + } + }, + "/templateversions/{templateversion}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get logs by template version", + "operationId": "get-logs-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/templateversions/{templateversion}/parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get parameters by template version", + "operationId": "get-parameters-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/parameter.ComputedValue" + } + } + } + } + } + }, + "/templateversions/{templateversion}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get resources by template version", + "operationId": "get-resources-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/templateversions/{templateversion}/rich-parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get rich parameters by template version", + "operationId": "get-rich-parameters-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionParameter" + } + } + } + } + } + }, + "/templateversions/{templateversion}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get schema by template version", + "operationId": "get-schema-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ParameterSchema" + } + } + } + } + } + }, + "/templateversions/{templateversion}/variables": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Templates" + ], + "summary": "Get template variables by template version", + "operationId": "get-template-variables-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionVariable" + } + } + } + } + } + }, + "/updatecheck": { + "get": { + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Update check", + "operationId": "update-check", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateCheckResponse" + } + } + } + } + }, + "/users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get users", + "operationId": "get-users", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query" + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GetUsersResponse" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create new user", + "operationId": "create-new-user", + "parameters": [ + { + "description": "Create user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/authmethods": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get authentication methods", + "operationId": "get-authentication-methods", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthMethods" + } + } + } + } + }, + "/users/first": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Check initial user created", + "operationId": "check-initial-user-created", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create initial user", + "operationId": "create-initial-user", + "parameters": [ + { + "description": "First user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserResponse" + } + } + } + } + }, + "/users/login": { + "post": { + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Authorization" + ], + "summary": "Log in user", + "operationId": "log-in-user", + "parameters": [ + { + "description": "Login request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordResponse" + } + } + } + } + }, + "/users/logout": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Log out user", + "operationId": "log-out-user", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/users/oauth2/github/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Users" + ], + "summary": "OAuth 2.0 GitHub Callback", + "operationId": "oauth-20-github-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/oidc/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Users" + ], + "summary": "OpenID Connect Callback", + "operationId": "openid-connect-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Members" + ], + "summary": "Get site member roles", + "operationId": "get-site-member-roles", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, + "/users/{user}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user by name", + "operationId": "get-user-by-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Delete user", + "operationId": "delete-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user Git SSH key", + "operationId": "get-user-git-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Regenerate user SSH key", + "operationId": "regenerate-user-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + } + }, + "/users/{user}/keys": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create new session key", + "operationId": "create-new-session-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, + "/users/{user}/keys/tokens": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user tokens", + "operationId": "get-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Create token API key", + "operationId": "create-token-api-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create token request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTokenRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, + "/users/{user}/keys/tokens/tokenconfig": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "General" + ], + "summary": "Get token config", + "operationId": "get-token-config", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TokenConfig" + } + } + } + } + }, + "/users/{user}/keys/tokens/{keyname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get API key by token name", + "operationId": "get-api-key-by-token-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "string", + "description": "Key Name", + "name": "keyname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "/users/{user}/keys/{keyid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get API key by ID", + "operationId": "get-api-key-by-id", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Users" + ], + "summary": "Delete API key", + "operationId": "delete-api-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/users/{user}/organizations": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get organizations by user", + "operationId": "get-organizations-by-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + } + }, + "/users/{user}/organizations/{organizationname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get organization by user and organization name", + "operationId": "get-organization-by-user-and-organization-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Organization name", + "name": "organizationname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/users/{user}/password": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update user password", + "operationId": "update-user-password", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update password request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserPasswordRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/users/{user}/profile": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Update user profile", + "operationId": "update-user-profile", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Updated profile", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserProfileRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Get user roles", + "operationId": "get-user-roles", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Assign role to user", + "operationId": "assign-role-to-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/status/activate": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Activate user account", + "operationId": "activate-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/status/suspend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Users" + ], + "summary": "Suspend user account", + "operationId": "suspend-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/workspace/{workspacename}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get workspace metadata by user and workspace name", + "operationId": "get-workspace-metadata-by-user-and-workspace-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Return data instead of HTTP 404 if the workspace is deleted", + "name": "include_deleted", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace build by user, workspace name, and build number", + "operationId": "get-workspace-build-by-user-workspace-name-and-build-number", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "number", + "description": "Build number", + "name": "buildnumber", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspace-quota/{user}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Enterprise" + ], + "summary": "Get workspace quota by user", + "operationId": "get-workspace-quota-by-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceQuota" + } + } + } + } + }, + "/workspaceagents/aws-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Authenticate agent on AWS instance", + "operationId": "authenticate-agent-on-aws-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.AWSInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/azure-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Authenticate agent on Azure instance", + "operationId": "authenticate-agent-on-azure-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.AzureInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/google-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Authenticate agent on Google Cloud instance", + "operationId": "authenticate-agent-on-google-cloud-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.GoogleInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/me/app-health": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace agent application health", + "operationId": "submit-workspace-agent-application-health", + "parameters": [ + { + "description": "Application health request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostAppHealthsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspaceagents/me/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "It accepts a WebSocket connection to an agent that listens to\nincoming connections and publishes node updates.", + "tags": [ + "Agents" + ], + "summary": "Coordinate workspace agent via Tailnet", + "operationId": "coordinate-workspace-agent-via-tailnet", + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/me/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get workspace agent Git auth", + "operationId": "get-workspace-agent-git-auth", + "parameters": [ + { + "type": "string", + "format": "uri", + "description": "Git URL", + "name": "url", + "in": "query", + "required": true + }, + { + "type": "boolean", + "description": "Wait for a new token to be issued", + "name": "listen", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.GitAuthResponse" + } + } + } + } + }, + "/workspaceagents/me/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get workspace agent Git SSH key", + "operationId": "get-workspace-agent-git-ssh-key", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.GitSSHKey" + } + } + } + } + }, + "/workspaceagents/me/metadata": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get authorized workspace agent metadata", + "operationId": "get-authorized-workspace-agent-metadata", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.Metadata" + } + } + } + } + }, + "/workspaceagents/me/report-lifecycle": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace agent lifecycle state", + "operationId": "submit-workspace-agent-lifecycle-state", + "parameters": [ + { + "description": "Workspace agent lifecycle request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostLifecycleRequest" + } + } + ], + "responses": { + "204": { + "description": "Success" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceagents/me/report-stats": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace agent stats", + "operationId": "submit-workspace-agent-stats", + "parameters": [ + { + "description": "Stats request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.Stats" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.StatsResponse" + } + } + } + } + }, + "/workspaceagents/me/startup": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Submit workspace agent startup", + "operationId": "submit-workspace-agent-startup", + "parameters": [ + { + "description": "Startup request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostStartupRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceagents/{workspaceagent}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get workspace agent by ID", + "operationId": "get-workspace-agent-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/connection": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get connection info for workspace agent", + "operationId": "get-connection-info-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentConnectionInfo" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Agents" + ], + "summary": "Coordinate workspace agent", + "operationId": "coordinate-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/{workspaceagent}/listening-ports": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Agents" + ], + "summary": "Get listening ports for workspace agent", + "operationId": "get-listening-ports-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPortsResponse" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/pty": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": [ + "Agents" + ], + "summary": "Open PTY to workspace agent", + "operationId": "open-pty-to-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspacebuilds/{workspacebuild}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace build", + "operationId": "get-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Cancel workspace build", + "operationId": "cancel-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace build logs", + "operationId": "get-workspace-build-logs", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get build parameters for workspace build", + "operationId": "get-build-parameters-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace resources for workspace build", + "operationId": "get-workspace-resources-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/state": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get provisioner state for workspace build", + "operationId": "get-provisioner-state-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspaces": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "List workspaces", + "operationId": "list-workspaces", + "parameters": [ + { + "type": "string", + "description": "Filter by owner username", + "name": "owner", + "in": "query" + }, + { + "type": "string", + "description": "Filter by template name", + "name": "template", + "in": "query" + }, + { + "type": "string", + "description": "Filter with partial-match by workspace name", + "name": "name", + "in": "query" + }, + { + "enum": [ + "pending", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleted", + "deleting" + ], + "type": "string", + "description": "Filter by workspace status", + "name": "status", + "in": "query" + }, + { + "enum": [ + "connected", + "connecting", + "disconnected", + "timeout" + ], + "type": "string", + "description": "Filter by agent status", + "name": "has_agent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspacesResponse" + } + } + } + } + }, + "/workspaces/{workspace}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Get workspace metadata by ID", + "operationId": "get-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Return data instead of HTTP 404 if the workspace is deleted", + "name": "include_deleted", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Update workspace metadata by ID", + "operationId": "update-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Metadata update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/autostart": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Update workspace autostart schedule by ID", + "operationId": "update-workspace-autostart-schedule-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Schedule update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/builds": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Get workspace builds by workspace ID", + "operationId": "get-workspace-builds-by-workspace-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Since timestamp", + "name": "since", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Builds" + ], + "summary": "Create workspace build", + "operationId": "create-workspace-build", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Create workspace build request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceBuildRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspaces/{workspace}/extend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Extend workspace deadline by ID", + "operationId": "extend-workspace-deadline-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Extend deadline update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PutExtendWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspaces/{workspace}/ttl": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": [ + "application/json" + ], + "tags": [ + "Workspaces" + ], + "summary": "Update workspace TTL by ID", + "operationId": "update-workspace-ttl-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Workspace TTL update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceTTLRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/watch": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": [ + "text/event-stream" + ], + "tags": [ + "Workspaces" + ], + "summary": "Watch workspace by ID", + "operationId": "watch-workspace-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + } + }, + "definitions": { + "agentsdk.AWSInstanceIdentityToken": { + "type": "object", + "required": [ + "document", + "signature" + ], + "properties": { + "document": { + "type": "string" + }, + "signature": { + "type": "string" + } } - ] }, - "default_refresh": { - "type": "string" - }, - "default_source_scheme": { - "enum": ["none", "data"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterSourceScheme" + "agentsdk.AuthenticateResponse": { + "type": "object", + "properties": { + "session_token": { + "type": "string" + } } - ] - }, - "default_source_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" }, - "job_id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "redisplay_value": { - "type": "boolean" - }, - "validation_condition": { - "type": "string" - }, - "validation_contains": { - "description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.", - "type": "array", - "items": { - "type": "string" - } - }, - "validation_error": { - "type": "string" - }, - "validation_type_system": { - "type": "string" - }, - "validation_value_type": { - "type": "string" - } - } - }, - "codersdk.ParameterScope": { - "type": "string", - "enum": ["template", "workspace", "import_job"], - "x-enum-varnames": [ - "ParameterTemplate", - "ParameterWorkspace", - "ParameterImportJob" - ] - }, - "codersdk.ParameterSourceScheme": { - "type": "string", - "enum": ["none", "data"], - "x-enum-varnames": [ - "ParameterSourceSchemeNone", - "ParameterSourceSchemeData" - ] - }, - "codersdk.PprofConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/clibase.HostPort" - }, - "enable": { - "type": "boolean" - } - } - }, - "codersdk.PrometheusConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/clibase.HostPort" - }, - "enable": { - "type": "boolean" - } - } - }, - "codersdk.ProvisionerConfig": { - "type": "object", - "properties": { - "daemon_poll_interval": { - "type": "integer" - }, - "daemon_poll_jitter": { - "type": "integer" - }, - "daemons": { - "type": "integer" - }, - "force_cancel_interval": { - "type": "integer" - } - } - }, - "codersdk.ProvisionerDaemon": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "provisioners": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "updated_at": { - "format": "date-time", - "allOf": [ - { - "$ref": "#/definitions/sql.NullTime" - } - ] - } - } - }, - "codersdk.ProvisionerJob": { - "type": "object", - "properties": { - "canceled_at": { - "type": "string", - "format": "date-time" - }, - "completed_at": { - "type": "string", - "format": "date-time" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "error": { - "type": "string" - }, - "error_code": { - "enum": ["MISSING_TEMPLATE_PARAMETER", "REQUIRED_TEMPLATE_VARIABLES"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.JobErrorCode" - } - ] - }, - "file_id": { - "type": "string", - "format": "uuid" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "started_at": { - "type": "string", - "format": "date-time" - }, - "status": { - "enum": [ - "pending", - "running", - "succeeded", - "canceling", - "canceled", - "failed" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerJobStatus" - } - ] - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "worker_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.ProvisionerJobLog": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "integer" - }, - "log_level": { - "enum": ["trace", "debug", "info", "warn", "error"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.LogLevel" + "agentsdk.AzureInstanceIdentityToken": { + "type": "object", + "required": [ + "encoding", + "signature" + ], + "properties": { + "encoding": { + "type": "string" + }, + "signature": { + "type": "string" + } } - ] - }, - "log_source": { - "$ref": "#/definitions/codersdk.LogSource" - }, - "output": { - "type": "string" - }, - "stage": { - "type": "string" - } - } - }, - "codersdk.ProvisionerJobStatus": { - "type": "string", - "enum": [ - "pending", - "running", - "succeeded", - "canceling", - "canceled", - "failed" - ], - "x-enum-varnames": [ - "ProvisionerJobPending", - "ProvisionerJobRunning", - "ProvisionerJobSucceeded", - "ProvisionerJobCanceling", - "ProvisionerJobCanceled", - "ProvisionerJobFailed" - ] - }, - "codersdk.ProvisionerStorageMethod": { - "type": "string", - "enum": ["file"], - "x-enum-varnames": ["ProvisionerStorageMethodFile"] - }, - "codersdk.PutExtendWorkspaceRequest": { - "type": "object", - "required": ["deadline"], - "properties": { - "deadline": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.RateLimitConfig": { - "type": "object", - "properties": { - "api": { - "type": "integer" - }, - "disable_all": { - "type": "boolean" - } - } - }, - "codersdk.Replica": { - "type": "object", - "properties": { - "created_at": { - "description": "CreatedAt is the timestamp when the replica was first seen.", - "type": "string", - "format": "date-time" - }, - "database_latency": { - "description": "DatabaseLatency is the latency in microseconds to the database.", - "type": "integer" - }, - "error": { - "description": "Error is the replica error.", - "type": "string" - }, - "hostname": { - "description": "Hostname is the hostname of the replica.", - "type": "string" - }, - "id": { - "description": "ID is the unique identifier for the replica.", - "type": "string", - "format": "uuid" - }, - "region_id": { - "description": "RegionID is the region of the replica.", - "type": "integer" - }, - "relay_address": { - "description": "RelayAddress is the accessible address to relay DERP connections.", - "type": "string" - } - } - }, - "codersdk.ResourceType": { - "type": "string", - "enum": [ - "template", - "template_version", - "user", - "workspace", - "workspace_build", - "git_ssh_key", - "api_key", - "group", - "license" - ], - "x-enum-varnames": [ - "ResourceTypeTemplate", - "ResourceTypeTemplateVersion", - "ResourceTypeUser", - "ResourceTypeWorkspace", - "ResourceTypeWorkspaceBuild", - "ResourceTypeGitSSHKey", - "ResourceTypeAPIKey", - "ResourceTypeGroup", - "ResourceTypeLicense" - ] - }, - "codersdk.Response": { - "type": "object", - "properties": { - "detail": { - "description": "Detail is a debug message that provides further insight into why the\naction failed. This information can be technical and a regular golang\nerr.Error() text.\n- \"database: too many open connections\"\n- \"stat: too many open files\"", - "type": "string" - }, - "message": { - "description": "Message is an actionable message that depicts actions the request took.\nThese messages should be fully formed sentences with proper punctuation.\nExamples:\n- \"A user has been created.\"\n- \"Failed to create a user.\"", - "type": "string" - }, - "validations": { - "description": "Validations are form field-specific friendly error messages. They will be\nshown on a form field in the UI. These can also be used to add additional\ncontext if there is a set of errors in the primary 'Message'.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ValidationError" - } - } - } - }, - "codersdk.Role": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - } - } - }, - "codersdk.SSHConfig": { - "type": "object", - "properties": { - "deploymentName": { - "description": "DeploymentName is the config-ssh Hostname prefix", - "type": "string" - }, - "sshconfigOptions": { - "description": "SSHConfigOptions are additional options to add to the ssh config file.\nThis will override defaults.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.SSHConfigResponse": { - "type": "object", - "properties": { - "hostname_prefix": { - "type": "string" - }, - "ssh_config_options": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - } - }, - "codersdk.ServiceBannerConfig": { - "type": "object", - "properties": { - "background_color": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "message": { - "type": "string" - } - } - }, - "codersdk.SessionCountDeploymentStats": { - "type": "object", - "properties": { - "jetbrains": { - "type": "integer" - }, - "reconnecting_pty": { - "type": "integer" - }, - "ssh": { - "type": "integer" - }, - "vscode": { - "type": "integer" - } - } - }, - "codersdk.SupportConfig": { - "type": "object", - "properties": { - "links": { - "$ref": "#/definitions/clibase.Struct-array_codersdk_LinkConfig" - } - } - }, - "codersdk.SwaggerConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - } - } - }, - "codersdk.TLSConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/clibase.HostPort" - }, - "cert_file": { - "type": "array", - "items": { - "type": "string" - } - }, - "client_auth": { - "type": "string" - }, - "client_ca_file": { - "type": "string" - }, - "client_cert_file": { - "type": "string" - }, - "client_key_file": { - "type": "string" - }, - "enable": { - "type": "boolean" - }, - "key_file": { - "type": "array", - "items": { - "type": "string" - } - }, - "min_version": { - "type": "string" - }, - "redirect_http": { - "type": "boolean" - } - } - }, - "codersdk.TelemetryConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - }, - "trace": { - "type": "boolean" - }, - "url": { - "$ref": "#/definitions/clibase.URL" - } - } - }, - "codersdk.Template": { - "type": "object", - "properties": { - "active_user_count": { - "description": "ActiveUserCount is set to -1 when loading.", - "type": "integer" - }, - "active_version_id": { - "type": "string", - "format": "uuid" - }, - "allow_user_cancel_workspace_jobs": { - "type": "boolean" - }, - "build_time_stats": { - "$ref": "#/definitions/codersdk.TemplateBuildTimeStats" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "created_by_id": { - "type": "string", - "format": "uuid" - }, - "created_by_name": { - "type": "string" - }, - "default_ttl_ms": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "max_ttl_ms": { - "description": "MaxTTLMillis is an enterprise feature. It's value is only used if your\nlicense is entitled to use the advanced template scheduling feature.", - "type": "integer" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "provisioner": { - "type": "string", - "enum": ["terraform"] - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.TemplateBuildTimeStats": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TransitionStats" - } - }, - "codersdk.TemplateDAUsResponse": { - "type": "object", - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.DAUEntry" - } - } - } - }, - "codersdk.TemplateExample": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "markdown": { - "type": "string" - }, - "name": { - "type": "string" }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "url": { - "type": "string" - } - } - }, - "codersdk.TemplateRole": { - "type": "string", - "enum": ["admin", "use", ""], - "x-enum-varnames": [ - "TemplateRoleAdmin", - "TemplateRoleUse", - "TemplateRoleDeleted" - ] - }, - "codersdk.TemplateUser": { - "type": "object", - "required": ["created_at", "email", "id", "username"], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "organization_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "role": { - "enum": ["admin", "use"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateRole" + "agentsdk.GitAuthResponse": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "url": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "agentsdk.GitSSHKey": { + "type": "object", + "properties": { + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } } - ] }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - }, - "status": { - "enum": ["active", "suspended"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" + "agentsdk.GoogleInstanceIdentityToken": { + "type": "object", + "required": [ + "json_web_token" + ], + "properties": { + "json_web_token": { + "type": "string" + } } - ] - }, - "username": { - "type": "string" - } - } - }, - "codersdk.TemplateVersion": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "created_by": { - "$ref": "#/definitions/codersdk.User" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "readme": { - "type": "string" - }, - "template_id": { - "type": "string", - "format": "uuid" }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.TemplateVersionGitAuth": { - "type": "object", - "properties": { - "authenticate_url": { - "type": "string" - }, - "authenticated": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/codersdk.GitProvider" - } - } - }, - "codersdk.TemplateVersionParameter": { - "type": "object", - "properties": { - "default_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "description_plaintext": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "legacy_variable_name": { - "type": "string" - }, - "mutable": { - "type": "boolean" - }, - "name": { - "type": "string" + "agentsdk.Metadata": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } + }, + "derpmap": { + "$ref": "#/definitions/tailcfg.DERPMap" + }, + "directory": { + "type": "string" + }, + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "git_auth_configs": { + "description": "GitAuthConfigs stores the number of Git configurations\nthe Coder deployment has. If this number is \u003e0, we\nset up special configuration in the workspace.", + "type": "integer" + }, + "motd_file": { + "type": "string" + }, + "shutdown_script": { + "type": "string" + }, + "shutdown_script_timeout": { + "type": "integer" + }, + "startup_script": { + "type": "string" + }, + "startup_script_timeout": { + "type": "integer" + }, + "vscode_port_proxy_uri": { + "type": "string" + } + } + }, + "agentsdk.PostAppHealthsRequest": { + "type": "object", + "properties": { + "healths": { + "description": "Healths is a map of the workspace app name and the health of the app.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.WorkspaceAppHealth" + } + } + } }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" - } + "agentsdk.PostLifecycleRequest": { + "type": "object", + "properties": { + "state": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" + } + } }, - "required": { - "type": "boolean" + "agentsdk.PostStartupRequest": { + "type": "object", + "properties": { + "expanded_directory": { + "type": "string" + }, + "version": { + "type": "string" + } + } }, - "type": { - "type": "string", - "enum": ["string", "number", "bool", "list(string)"] + "agentsdk.Stats": { + "type": "object", + "properties": { + "connection_count": { + "description": "ConnectionCount is the number of connections received by an agent.", + "type": "integer" + }, + "connection_median_latency_ms": { + "description": "ConnectionMedianLatencyMS is the median latency of all connections in milliseconds.", + "type": "number" + }, + "connections_by_proto": { + "description": "ConnectionsByProto is a count of connections by protocol.", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "rx_bytes": { + "description": "RxBytes is the number of received bytes.", + "type": "integer" + }, + "rx_packets": { + "description": "RxPackets is the number of received packets.", + "type": "integer" + }, + "session_count_jetbrains": { + "description": "SessionCountJetBrains is the number of connections received by an agent\nthat are from our JetBrains extension.", + "type": "integer" + }, + "session_count_reconnecting_pty": { + "description": "SessionCountReconnectingPTY is the number of connections received by an agent\nthat are from the reconnecting web terminal.", + "type": "integer" + }, + "session_count_ssh": { + "description": "SessionCountSSH is the number of connections received by an agent\nthat are normal, non-tagged SSH sessions.", + "type": "integer" + }, + "session_count_vscode": { + "description": "SessionCountVSCode is the number of connections received by an agent\nthat are from our VS Code extension.", + "type": "integer" + }, + "tx_bytes": { + "description": "TxBytes is the number of transmitted bytes.", + "type": "integer" + }, + "tx_packets": { + "description": "TxPackets is the number of transmitted bytes.", + "type": "integer" + } + } + }, + "agentsdk.StatsResponse": { + "type": "object", + "properties": { + "report_interval": { + "description": "ReportInterval is the duration after which the agent should send stats\nagain.", + "type": "integer" + } + } }, - "validation_error": { - "type": "string" + "clibase.Annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } }, - "validation_max": { - "type": "integer" + "clibase.Group": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/clibase.Group" + } + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent": { + "$ref": "#/definitions/clibase.Group" + } + } + }, + "clibase.HostPort": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "string" + } + } }, - "validation_min": { - "type": "integer" + "clibase.Option": { + "type": "object", + "properties": { + "annotations": { + "description": "Annotations enable extensions to clibase higher up in the stack. It's useful for\nhelp formatting and documentation generation.", + "allOf": [ + { + "$ref": "#/definitions/clibase.Annotations" + } + ] + }, + "default": { + "description": "Default is parsed into Value if set.", + "type": "string" + }, + "description": { + "type": "string" + }, + "env": { + "description": "Env is the environment variable used to configure this option. If unset,\nenvironment configuring is disabled.", + "type": "string" + }, + "flag": { + "description": "Flag is the long name of the flag used to configure this option. If unset,\nflag configuring is disabled.", + "type": "string" + }, + "flag_shorthand": { + "description": "FlagShorthand is the one-character shorthand for the flag. If unset, no\nshorthand is used.", + "type": "string" + }, + "group": { + "description": "Group is a group hierarchy that helps organize this option in help, configs\nand other documentation.", + "allOf": [ + { + "$ref": "#/definitions/clibase.Group" + } + ] + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "use_instead": { + "description": "UseInstead is a list of options that should be used instead of this one.\nThe field is used to generate a deprecation warning.", + "type": "array", + "items": { + "$ref": "#/definitions/clibase.Option" + } + }, + "value": { + "description": "Value includes the types listed in values.go." + }, + "yaml": { + "description": "YAML is the YAML key used to configure this option. If unset, YAML\nconfiguring is disabled.", + "type": "string" + } + } + }, + "clibase.Struct-array_codersdk_GitAuthConfig": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.GitAuthConfig" + } + } + } }, - "validation_monotonic": { - "enum": ["increasing", "decreasing"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ValidationMonotonicOrder" + "clibase.Struct-array_codersdk_LinkConfig": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.LinkConfig" + } + } } - ] }, - "validation_regex": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionParameterOption": { - "type": "object", - "properties": { - "description": { - "type": "string" + "clibase.URL": { + "type": "object", + "properties": { + "forceQuery": { + "description": "append a query ('?') even if RawQuery is empty", + "type": "boolean" + }, + "fragment": { + "description": "fragment for references, without '#'", + "type": "string" + }, + "host": { + "description": "host or host:port", + "type": "string" + }, + "omitHost": { + "description": "do not emit empty host (authority)", + "type": "boolean" + }, + "opaque": { + "description": "encoded opaque data", + "type": "string" + }, + "path": { + "description": "path (relative paths may omit leading slash)", + "type": "string" + }, + "rawFragment": { + "description": "encoded fragment hint (see EscapedFragment method)", + "type": "string" + }, + "rawPath": { + "description": "encoded path hint (see EscapedPath method)", + "type": "string" + }, + "rawQuery": { + "description": "encoded query values, without '?'", + "type": "string" + }, + "scheme": { + "type": "string" + }, + "user": { + "description": "username and password information", + "allOf": [ + { + "$ref": "#/definitions/url.Userinfo" + } + ] + } + } + }, + "coderd.SCIMUser": { + "type": "object", + "properties": { + "active": { + "type": "boolean" + }, + "emails": { + "type": "array", + "items": { + "type": "object", + "properties": { + "display": { + "type": "string" + }, + "primary": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string", + "format": "email" + } + } + } + }, + "groups": { + "type": "array", + "items": {} + }, + "id": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "resourceType": { + "type": "string" + } + } + }, + "name": { + "type": "object", + "properties": { + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + } + } + }, + "schemas": { + "type": "array", + "items": { + "type": "string" + } + }, + "userName": { + "type": "string" + } + } + }, + "coderd.cspViolation": { + "type": "object", + "properties": { + "csp-report": { + "type": "object", + "additionalProperties": true + } + } }, - "icon": { - "type": "string" + "codersdk.APIKey": { + "type": "object", + "required": [ + "created_at", + "expires_at", + "id", + "last_used", + "lifetime_seconds", + "login_type", + "scope", + "token_name", + "updated_at", + "user_id" + ], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "last_used": { + "type": "string", + "format": "date-time" + }, + "lifetime_seconds": { + "type": "integer" + }, + "login_type": { + "enum": [ + "password", + "github", + "oidc", + "token" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.LoginType" + } + ] + }, + "scope": { + "enum": [ + "all", + "application_connect" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.APIKeyScope" + } + ] + }, + "token_name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.APIKeyScope": { + "type": "string", + "enum": [ + "all", + "application_connect" + ], + "x-enum-varnames": [ + "APIKeyScopeAll", + "APIKeyScopeApplicationConnect" + ] }, - "name": { - "type": "string" + "codersdk.AddLicenseRequest": { + "type": "object", + "required": [ + "license" + ], + "properties": { + "license": { + "type": "string" + } + } }, - "value": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionVariable": { - "type": "object", - "properties": { - "default_value": { - "type": "string" + "codersdk.AppHostResponse": { + "type": "object", + "properties": { + "host": { + "description": "Host is the externally accessible URL for the Coder instance.", + "type": "string" + } + } }, - "description": { - "type": "string" + "codersdk.AppearanceConfig": { + "type": "object", + "properties": { + "logo_url": { + "type": "string" + }, + "service_banner": { + "$ref": "#/definitions/codersdk.ServiceBannerConfig" + }, + "support_links": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.LinkConfig" + } + } + } + }, + "codersdk.AssignableRoles": { + "type": "object", + "properties": { + "assignable": { + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } }, - "name": { - "type": "string" + "codersdk.AuditAction": { + "type": "string", + "enum": [ + "create", + "write", + "delete", + "start", + "stop", + "login", + "logout" + ], + "x-enum-varnames": [ + "AuditActionCreate", + "AuditActionWrite", + "AuditActionDelete", + "AuditActionStart", + "AuditActionStop", + "AuditActionLogin", + "AuditActionLogout" + ] + }, + "codersdk.AuditDiff": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuditDiffField" + } }, - "required": { - "type": "boolean" + "codersdk.AuditDiffField": { + "type": "object", + "properties": { + "new": {}, + "old": {}, + "secret": { + "type": "boolean" + } + } }, - "sensitive": { - "type": "boolean" + "codersdk.AuditLog": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/codersdk.AuditAction" + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "type": "string" + }, + "diff": { + "$ref": "#/definitions/codersdk.AuditDiff" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "ip": { + "type": "string" + }, + "is_deleted": { + "type": "boolean" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "request_id": { + "type": "string", + "format": "uuid" + }, + "resource_icon": { + "type": "string" + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "resource_link": { + "type": "string" + }, + "resource_target": { + "description": "ResourceTarget is the name of the resource.", + "type": "string" + }, + "resource_type": { + "$ref": "#/definitions/codersdk.ResourceType" + }, + "status_code": { + "type": "integer" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "user": { + "$ref": "#/definitions/codersdk.User" + }, + "user_agent": { + "type": "string" + } + } + }, + "codersdk.AuditLogResponse": { + "type": "object", + "properties": { + "audit_logs": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AuditLog" + } + }, + "count": { + "type": "integer" + } + } + }, + "codersdk.AuthMethod": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } }, - "type": { - "type": "string", - "enum": ["string", "number", "bool"] + "codersdk.AuthMethods": { + "type": "object", + "properties": { + "github": { + "$ref": "#/definitions/codersdk.AuthMethod" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCAuthMethod" + }, + "password": { + "$ref": "#/definitions/codersdk.AuthMethod" + } + } + }, + "codersdk.AuthorizationCheck": { + "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": [ + "create", + "read", + "update", + "delete" + ] + }, + "object": { + "description": "Object can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product.\nWhen defining an object, use the most specific language when possible to\nproduce the smallest set. Meaning to set as many fields on 'Object' as\nyou can. Example, if you want to check if you can update all workspaces\nowned by 'me', try to also add an 'OrganizationID' to the settings.\nOmitting the 'OrganizationID' could produce the incorrect value, as\nworkspaces have both `user` and `organization` owners.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.AuthorizationObject" + } + ] + } + } + }, + "codersdk.AuthorizationObject": { + "description": "AuthorizationObject can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.", + "type": "object", + "properties": { + "organization_id": { + "description": "OrganizationID (optional) adds the set constraint to all resources owned by a given organization.", + "type": "string" + }, + "owner_id": { + "description": "OwnerID (optional) adds the set constraint to all resources owned by a given user.", + "type": "string" + }, + "resource_id": { + "description": "ResourceID (optional) reduces the set to a singular resource. This assigns\na resource ID to the resource type, eg: a single workspace.\nThe rbac library will not fetch the resource from the database, so if you\nare using this option, you should also set the owner ID and organization ID\nif possible. Be as specific as possible using all the fields relevant.", + "type": "string" + }, + "resource_type": { + "description": "ResourceType is the name of the resource.\n`./coderd/rbac/object.go` has the list of valid resource types.", + "type": "string" + } + } + }, + "codersdk.AuthorizationRequest": { + "type": "object", + "properties": { + "checks": { + "description": "Checks is a map keyed with an arbitrary string to a permission check.\nThe key can be any string that is helpful to the caller, and allows\nmultiple permission checks to be run in a single request.\nThe key ensures that each permission check has the same key in the\nresponse.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuthorizationCheck" + } + } + } }, - "value": { - "type": "string" - } - } - }, - "codersdk.TokenConfig": { - "type": "object", - "properties": { - "max_token_lifetime": { - "type": "integer" - } - } - }, - "codersdk.TraceConfig": { - "type": "object", - "properties": { - "capture_logs": { - "type": "boolean" + "codersdk.AuthorizationResponse": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } }, - "enable": { - "type": "boolean" + "codersdk.BuildInfoResponse": { + "type": "object", + "properties": { + "external_url": { + "description": "ExternalURL references the current Coder version.\nFor production builds, this will link directly to a release. For development builds, this will link to a commit.", + "type": "string" + }, + "version": { + "description": "Version returns the semantic version of the build.", + "type": "string" + } + } }, - "honeycomb_api_key": { - "type": "string" - } - } - }, - "codersdk.TransitionStats": { - "type": "object", - "properties": { - "p50": { - "type": "integer", - "example": 123 - }, - "p95": { - "type": "integer", - "example": 146 - } - } - }, - "codersdk.UpdateActiveTemplateVersion": { - "type": "object", - "required": ["id"], - "properties": { - "id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.UpdateAppearanceConfig": { - "type": "object", - "properties": { - "logo_url": { - "type": "string" - }, - "service_banner": { - "$ref": "#/definitions/codersdk.ServiceBannerConfig" - } - } - }, - "codersdk.UpdateCheckResponse": { - "type": "object", - "properties": { - "current": { - "description": "Current indicates whether the server version is the same as the latest.", - "type": "boolean" - }, - "url": { - "description": "URL to download the latest release of Coder.", - "type": "string" - }, - "version": { - "description": "Version is the semantic version for the latest release of Coder.", - "type": "string" - } - } - }, - "codersdk.UpdateRoles": { - "type": "object", - "properties": { - "roles": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.UpdateTemplateACL": { - "type": "object", - "properties": { - "group_perms": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TemplateRole" - } - }, - "user_perms": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TemplateRole" - } - } - } - }, - "codersdk.UpdateUserPasswordRequest": { - "type": "object", - "required": ["password"], - "properties": { - "old_password": { - "type": "string" - }, - "password": { - "type": "string" - } - } - }, - "codersdk.UpdateUserProfileRequest": { - "type": "object", - "required": ["username"], - "properties": { - "username": { - "type": "string" - } - } - }, - "codersdk.UpdateWorkspaceAutostartRequest": { - "type": "object", - "properties": { - "schedule": { - "type": "string" - } - } - }, - "codersdk.UpdateWorkspaceRequest": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } - }, - "codersdk.UpdateWorkspaceTTLRequest": { - "type": "object", - "properties": { - "ttl_ms": { - "type": "integer" - } - } - }, - "codersdk.UploadResponse": { - "type": "object", - "properties": { - "hash": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.User": { - "type": "object", - "required": ["created_at", "email", "id", "username"], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "organization_ids": { - "type": "array", - "items": { + "codersdk.BuildReason": { "type": "string", - "format": "uuid" - } + "enum": [ + "initiator", + "autostart", + "autostop" + ], + "x-enum-varnames": [ + "BuildReasonInitiator", + "BuildReasonAutostart", + "BuildReasonAutostop" + ] }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } + "codersdk.CreateFirstUserRequest": { + "type": "object", + "required": [ + "email", + "password", + "username" + ], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "trial": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateFirstUserResponse": { + "type": "object", + "properties": { + "organization_id": { + "type": "string", + "format": "uuid" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } }, - "status": { - "enum": ["active", "suspended"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" + "codersdk.CreateGroupRequest": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "quota_allowance": { + "type": "integer" + } + } + }, + "codersdk.CreateOrganizationRequest": { + "type": "object", + "required": [ + "name" + ], + "properties": { + "name": { + "type": "string" + } } - ] }, - "username": { - "type": "string" - } - } - }, - "codersdk.UserStatus": { - "type": "string", - "enum": ["active", "suspended"], - "x-enum-varnames": ["UserStatusActive", "UserStatusSuspended"] - }, - "codersdk.ValidationError": { - "type": "object", - "required": ["detail", "field"], - "properties": { - "detail": { - "type": "string" - }, - "field": { - "type": "string" - } - } - }, - "codersdk.ValidationMonotonicOrder": { - "type": "string", - "enum": ["increasing", "decreasing"], - "x-enum-varnames": [ - "MonotonicOrderIncreasing", - "MonotonicOrderDecreasing" - ] - }, - "codersdk.VariableValue": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.Workspace": { - "type": "object", - "properties": { - "autostart_schedule": { - "type": "string" + "codersdk.CreateParameterRequest": { + "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", + "type": "object", + "required": [ + "destination_scheme", + "name", + "source_scheme", + "source_value" + ], + "properties": { + "copy_from_parameter": { + "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", + "type": "string", + "format": "uuid" + }, + "destination_scheme": { + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterDestinationScheme" + } + ] + }, + "name": { + "type": "string" + }, + "source_scheme": { + "enum": [ + "none", + "data" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterSourceScheme" + } + ] + }, + "source_value": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateRequest": { + "type": "object", + "required": [ + "name", + "template_version_id" + ], + "properties": { + "allow_user_cancel_workspace_jobs": { + "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", + "type": "boolean" + }, + "default_ttl_ms": { + "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", + "type": "integer" + }, + "description": { + "description": "Description is a description of what the template contains. It must be\nless than 128 bytes.", + "type": "string" + }, + "display_name": { + "description": "DisplayName is the displayed name of the template.", + "type": "string" + }, + "icon": { + "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", + "type": "string" + }, + "max_ttl_ms": { + "description": "MaxTTLMillis allows optionally specifying the max lifetime for\nworkspaces created from this template.", + "type": "integer" + }, + "name": { + "description": "Name is the name of the template.", + "type": "string" + }, + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "template_version_id": { + "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.CreateTemplateVersionDryRunRequest": { + "type": "object", + "properties": { + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "user_variable_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.VariableValue" + } + }, + "workspace_name": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateVersionRequest": { + "type": "object", + "required": [ + "provisioner", + "storage_method" + ], + "properties": { + "example_id": { + "type": "string" + }, + "file_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "parameter_values": { + "description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "provisioner": { + "type": "string", + "enum": [ + "terraform", + "echo" + ] + }, + "storage_method": { + "enum": [ + "file" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerStorageMethod" + } + ] + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "template_id": { + "description": "TemplateID optionally associates a version with a template.", + "type": "string", + "format": "uuid" + }, + "user_variable_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.VariableValue" + } + } + } + }, + "codersdk.CreateTestAuditLogRequest": { + "type": "object", + "properties": { + "action": { + "enum": [ + "create", + "write", + "delete", + "start", + "stop" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.AuditAction" + } + ] + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "build_reason": { + "enum": [ + "autostart", + "autostop", + "initiator" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.BuildReason" + } + ] + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "resource_type": { + "enum": [ + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "auditable_group" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ResourceType" + } + ] + }, + "time": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.CreateTokenRequest": { + "type": "object", + "properties": { + "lifetime": { + "type": "integer" + }, + "scope": { + "enum": [ + "all", + "application_connect" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.APIKeyScope" + } + ] + }, + "token_name": { + "type": "string" + } + } + }, + "codersdk.CreateUserRequest": { + "type": "object", + "required": [ + "email", + "organization_id", + "password", + "username" + ], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateWorkspaceBuildRequest": { + "type": "object", + "required": [ + "transition" + ], + "properties": { + "dry_run": { + "type": "boolean" + }, + "orphan": { + "description": "Orphan may be set for the Destroy transition.", + "type": "boolean" + }, + "parameter_values": { + "description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "state": { + "type": "array", + "items": { + "type": "integer" + } + }, + "template_version_id": { + "type": "string", + "format": "uuid" + }, + "transition": { + "enum": [ + "create", + "start", + "stop", + "delete" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + } + } + }, + "codersdk.CreateWorkspaceRequest": { + "type": "object", + "required": [ + "name", + "template_id" + ], + "properties": { + "autostart_schedule": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parameter_values": { + "description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "ttl_ms": { + "type": "integer" + } + } + }, + "codersdk.DAUEntry": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "date": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.DERP": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DERPConfig" + }, + "server": { + "$ref": "#/definitions/codersdk.DERPServerConfig" + } + } }, - "created_at": { - "type": "string", - "format": "date-time" + "codersdk.DERPConfig": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "url": { + "type": "string" + } + } }, - "id": { - "type": "string", - "format": "uuid" + "codersdk.DERPRegion": { + "type": "object", + "properties": { + "latency_ms": { + "type": "number" + }, + "preferred": { + "type": "boolean" + } + } }, - "last_used_at": { - "type": "string", - "format": "date-time" + "codersdk.DERPServerConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "region_code": { + "type": "string" + }, + "region_id": { + "type": "integer" + }, + "region_name": { + "type": "string" + }, + "relay_url": { + "$ref": "#/definitions/clibase.URL" + }, + "stun_addresses": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.DangerousConfig": { + "type": "object", + "properties": { + "allow_path_app_sharing": { + "type": "boolean" + }, + "allow_path_app_site_owner_access": { + "type": "boolean" + } + } }, - "latest_build": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" + "codersdk.DeploymentConfig": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DeploymentValues" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/clibase.Option" + } + } + } + }, + "codersdk.DeploymentDAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + } + } }, - "name": { - "type": "string" + "codersdk.DeploymentStats": { + "type": "object", + "properties": { + "aggregated_from": { + "description": "AggregatedFrom is the time in which stats are aggregated from.\nThis might be back in time a specific duration or interval.", + "type": "string", + "format": "date-time" + }, + "collected_at": { + "description": "CollectedAt is the time in which stats are collected at.", + "type": "string", + "format": "date-time" + }, + "next_update_at": { + "description": "NextUpdateAt is the time when the next batch of stats will\nbe updated.", + "type": "string", + "format": "date-time" + }, + "session_count": { + "$ref": "#/definitions/codersdk.SessionCountDeploymentStats" + }, + "workspaces": { + "$ref": "#/definitions/codersdk.WorkspaceDeploymentStats" + } + } + }, + "codersdk.DeploymentValues": { + "type": "object", + "properties": { + "access_url": { + "$ref": "#/definitions/clibase.URL" + }, + "address": { + "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", + "allOf": [ + { + "$ref": "#/definitions/clibase.HostPort" + } + ] + }, + "agent_fallback_troubleshooting_url": { + "$ref": "#/definitions/clibase.URL" + }, + "agent_stat_refresh_interval": { + "type": "integer" + }, + "audit_logging": { + "type": "boolean" + }, + "autobuild_poll_interval": { + "type": "integer" + }, + "browser_only": { + "type": "boolean" + }, + "cache_directory": { + "type": "string" + }, + "config": { + "type": "string" + }, + "config_ssh": { + "$ref": "#/definitions/codersdk.SSHConfig" + }, + "dangerous": { + "$ref": "#/definitions/codersdk.DangerousConfig" + }, + "derp": { + "$ref": "#/definitions/codersdk.DERP" + }, + "disable_password_auth": { + "type": "boolean" + }, + "disable_path_apps": { + "type": "boolean" + }, + "disable_session_expiry_refresh": { + "type": "boolean" + }, + "experiments": { + "type": "array", + "items": { + "type": "string" + } + }, + "git_auth": { + "$ref": "#/definitions/clibase.Struct-array_codersdk_GitAuthConfig" + }, + "http_address": { + "description": "HTTPAddress is a string because it may be set to zero to disable.", + "type": "string" + }, + "in_memory_database": { + "type": "boolean" + }, + "logging": { + "$ref": "#/definitions/codersdk.LoggingConfig" + }, + "max_session_expiry": { + "type": "integer" + }, + "max_token_lifetime": { + "type": "integer" + }, + "metrics_cache_refresh_interval": { + "type": "integer" + }, + "oauth2": { + "$ref": "#/definitions/codersdk.OAuth2Config" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCConfig" + }, + "pg_connection_url": { + "type": "string" + }, + "pprof": { + "$ref": "#/definitions/codersdk.PprofConfig" + }, + "prometheus": { + "$ref": "#/definitions/codersdk.PrometheusConfig" + }, + "provisioner": { + "$ref": "#/definitions/codersdk.ProvisionerConfig" + }, + "proxy_trusted_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "proxy_trusted_origins": { + "type": "array", + "items": { + "type": "string" + } + }, + "rate_limit": { + "$ref": "#/definitions/codersdk.RateLimitConfig" + }, + "redirect_to_access_url": { + "type": "boolean" + }, + "scim_api_key": { + "type": "string" + }, + "secure_auth_cookie": { + "type": "boolean" + }, + "ssh_keygen_algorithm": { + "type": "string" + }, + "strict_transport_security": { + "type": "integer" + }, + "strict_transport_security_options": { + "type": "array", + "items": { + "type": "string" + } + }, + "support": { + "$ref": "#/definitions/codersdk.SupportConfig" + }, + "swagger": { + "$ref": "#/definitions/codersdk.SwaggerConfig" + }, + "telemetry": { + "$ref": "#/definitions/codersdk.TelemetryConfig" + }, + "tls": { + "$ref": "#/definitions/codersdk.TLSConfig" + }, + "trace": { + "$ref": "#/definitions/codersdk.TraceConfig" + }, + "update_check": { + "type": "boolean" + }, + "verbose": { + "type": "boolean" + }, + "wildcard_access_url": { + "$ref": "#/definitions/clibase.URL" + }, + "write_config": { + "type": "boolean" + } + } + }, + "codersdk.Entitlement": { + "type": "string", + "enum": [ + "entitled", + "grace_period", + "not_entitled" + ], + "x-enum-varnames": [ + "EntitlementEntitled", + "EntitlementGracePeriod", + "EntitlementNotEntitled" + ] }, - "organization_id": { - "type": "string", - "format": "uuid" + "codersdk.Entitlements": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "type": "string" + } + }, + "features": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.Feature" + } + }, + "has_license": { + "type": "boolean" + }, + "require_telemetry": { + "type": "boolean" + }, + "trial": { + "type": "boolean" + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.Experiment": { + "type": "string", + "enum": [ + "authz_querier", + "template_editor" + ], + "x-enum-varnames": [ + "ExperimentAuthzQuerier", + "ExperimentTemplateEditor" + ] }, - "outdated": { - "type": "boolean" + "codersdk.Feature": { + "type": "object", + "properties": { + "actual": { + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "entitlement": { + "$ref": "#/definitions/codersdk.Entitlement" + }, + "limit": { + "type": "integer" + } + } + }, + "codersdk.GenerateAPIKeyResponse": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } }, - "owner_id": { - "type": "string", - "format": "uuid" + "codersdk.GetUsersResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "codersdk.GitAuthConfig": { + "type": "object", + "properties": { + "auth_url": { + "type": "string" + }, + "client_id": { + "type": "string" + }, + "id": { + "type": "string" + }, + "no_refresh": { + "type": "boolean" + }, + "regex": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "token_url": { + "type": "string" + }, + "type": { + "type": "string" + }, + "validate_url": { + "type": "string" + } + } + }, + "codersdk.GitProvider": { + "type": "string", + "enum": [ + "azure-devops", + "github", + "gitlab", + "bitbucket" + ], + "x-enum-varnames": [ + "GitProviderAzureDevops", + "GitProviderGitHub", + "GitProviderGitLab", + "GitProviderBitBucket" + ] + }, + "codersdk.GitSSHKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.Group": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "quota_allowance": { + "type": "integer" + } + } + }, + "codersdk.Healthcheck": { + "type": "object", + "properties": { + "interval": { + "description": "Interval specifies the seconds between each health check.", + "type": "integer" + }, + "threshold": { + "description": "Threshold specifies the number of consecutive failed health checks before returning \"unhealthy\".", + "type": "integer" + }, + "url": { + "description": "URL specifies the endpoint to check for the app health.", + "type": "string" + } + } + }, + "codersdk.JobErrorCode": { + "type": "string", + "enum": [ + "MISSING_TEMPLATE_PARAMETER", + "REQUIRED_TEMPLATE_VARIABLES" + ], + "x-enum-varnames": [ + "MissingTemplateParameter", + "RequiredTemplateVariables" + ] }, - "owner_name": { - "type": "string" + "codersdk.License": { + "type": "object", + "properties": { + "claims": { + "description": "Claims are the JWT claims asserted by the license. Here we use\na generic string map to ensure that all data from the server is\nparsed verbatim, not just the fields this version of Coder\nunderstands.", + "type": "object", + "additionalProperties": true + }, + "id": { + "type": "integer" + }, + "uploaded_at": { + "type": "string", + "format": "date-time" + }, + "uuid": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.LinkConfig": { + "type": "object", + "properties": { + "icon": { + "type": "string" + }, + "name": { + "type": "string" + }, + "target": { + "type": "string" + } + } }, - "template_allow_user_cancel_workspace_jobs": { - "type": "boolean" + "codersdk.LogLevel": { + "type": "string", + "enum": [ + "trace", + "debug", + "info", + "warn", + "error" + ], + "x-enum-varnames": [ + "LogLevelTrace", + "LogLevelDebug", + "LogLevelInfo", + "LogLevelWarn", + "LogLevelError" + ] }, - "template_display_name": { - "type": "string" + "codersdk.LogSource": { + "type": "string", + "enum": [ + "provisioner_daemon", + "provisioner" + ], + "x-enum-varnames": [ + "LogSourceProvisionerDaemon", + "LogSourceProvisioner" + ] }, - "template_icon": { - "type": "string" + "codersdk.LoggingConfig": { + "type": "object", + "properties": { + "human": { + "type": "string" + }, + "json": { + "type": "string" + }, + "stackdriver": { + "type": "string" + } + } }, - "template_id": { - "type": "string", - "format": "uuid" + "codersdk.LoginType": { + "type": "string", + "enum": [ + "password", + "github", + "oidc", + "token" + ], + "x-enum-varnames": [ + "LoginTypePassword", + "LoginTypeGithub", + "LoginTypeOIDC", + "LoginTypeToken" + ] + }, + "codersdk.LoginWithPasswordRequest": { + "type": "object", + "required": [ + "email", + "password" + ], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string" + } + } }, - "template_name": { - "type": "string" + "codersdk.LoginWithPasswordResponse": { + "type": "object", + "required": [ + "session_token" + ], + "properties": { + "session_token": { + "type": "string" + } + } }, - "ttl_ms": { - "type": "integer" + "codersdk.OAuth2Config": { + "type": "object", + "properties": { + "github": { + "$ref": "#/definitions/codersdk.OAuth2GithubConfig" + } + } }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.WorkspaceAgent": { - "type": "object", - "properties": { - "apps": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceApp" - } + "codersdk.OAuth2GithubConfig": { + "type": "object", + "properties": { + "allow_everyone": { + "type": "boolean" + }, + "allow_signups": { + "type": "boolean" + }, + "allowed_orgs": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_teams": { + "type": "array", + "items": { + "type": "string" + } + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "enterprise_base_url": { + "type": "string" + } + } + }, + "codersdk.OIDCAuthMethod": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "iconUrl": { + "type": "string" + }, + "signInText": { + "type": "string" + } + } + }, + "codersdk.OIDCConfig": { + "type": "object", + "properties": { + "allow_signups": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "email_domain": { + "type": "array", + "items": { + "type": "string" + } + }, + "groups_field": { + "type": "string" + }, + "icon_url": { + "$ref": "#/definitions/clibase.URL" + }, + "ignore_email_verified": { + "type": "boolean" + }, + "issuer_url": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "sign_in_text": { + "type": "string" + }, + "username_field": { + "type": "string" + } + } + }, + "codersdk.Organization": { + "type": "object", + "required": [ + "created_at", + "id", + "name", + "updated_at" + ], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.OrganizationMember": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.Parameter": { + "description": "Parameter represents a set value for the scope.", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "destination_scheme": { + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterDestinationScheme" + } + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "scope": { + "enum": [ + "template", + "workspace", + "import_job" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterScope" + } + ] + }, + "scope_id": { + "type": "string", + "format": "uuid" + }, + "source_scheme": { + "enum": [ + "none", + "data" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterSourceScheme" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.ParameterDestinationScheme": { + "type": "string", + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ], + "x-enum-varnames": [ + "ParameterDestinationSchemeNone", + "ParameterDestinationSchemeEnvironmentVariable", + "ParameterDestinationSchemeProvisionerVariable" + ] }, - "architecture": { - "type": "string" + "codersdk.ParameterSchema": { + "type": "object", + "properties": { + "allow_override_destination": { + "type": "boolean" + }, + "allow_override_source": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "default_destination_scheme": { + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterDestinationScheme" + } + ] + }, + "default_refresh": { + "type": "string" + }, + "default_source_scheme": { + "enum": [ + "none", + "data" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterSourceScheme" + } + ] + }, + "default_source_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "redisplay_value": { + "type": "boolean" + }, + "validation_condition": { + "type": "string" + }, + "validation_contains": { + "description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.", + "type": "array", + "items": { + "type": "string" + } + }, + "validation_error": { + "type": "string" + }, + "validation_type_system": { + "type": "string" + }, + "validation_value_type": { + "type": "string" + } + } + }, + "codersdk.ParameterScope": { + "type": "string", + "enum": [ + "template", + "workspace", + "import_job" + ], + "x-enum-varnames": [ + "ParameterTemplate", + "ParameterWorkspace", + "ParameterImportJob" + ] }, - "connection_timeout_seconds": { - "type": "integer" + "codersdk.ParameterSourceScheme": { + "type": "string", + "enum": [ + "none", + "data" + ], + "x-enum-varnames": [ + "ParameterSourceSchemeNone", + "ParameterSourceSchemeData" + ] }, - "created_at": { - "type": "string", - "format": "date-time" + "codersdk.PprofConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/clibase.HostPort" + }, + "enable": { + "type": "boolean" + } + } }, - "directory": { - "type": "string" + "codersdk.PrometheusConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/clibase.HostPort" + }, + "enable": { + "type": "boolean" + } + } }, - "disconnected_at": { - "type": "string", - "format": "date-time" + "codersdk.ProvisionerConfig": { + "type": "object", + "properties": { + "daemon_poll_interval": { + "type": "integer" + }, + "daemon_poll_jitter": { + "type": "integer" + }, + "daemons": { + "type": "integer" + }, + "force_cancel_interval": { + "type": "integer" + } + } + }, + "codersdk.ProvisionerDaemon": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "provisioners": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "updated_at": { + "format": "date-time", + "allOf": [ + { + "$ref": "#/definitions/sql.NullTime" + } + ] + } + } + }, + "codersdk.ProvisionerJob": { + "type": "object", + "properties": { + "canceled_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": "string" + }, + "error_code": { + "enum": [ + "MISSING_TEMPLATE_PARAMETER", + "REQUIRED_TEMPLATE_VARIABLES" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.JobErrorCode" + } + ] + }, + "file_id": { + "type": "string", + "format": "uuid" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "status": { + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerJobStatus" + } + ] + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "worker_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.ProvisionerJobLog": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "integer" + }, + "log_level": { + "enum": [ + "trace", + "debug", + "info", + "warn", + "error" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.LogLevel" + } + ] + }, + "log_source": { + "$ref": "#/definitions/codersdk.LogSource" + }, + "output": { + "type": "string" + }, + "stage": { + "type": "string" + } + } + }, + "codersdk.ProvisionerJobStatus": { + "type": "string", + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ], + "x-enum-varnames": [ + "ProvisionerJobPending", + "ProvisionerJobRunning", + "ProvisionerJobSucceeded", + "ProvisionerJobCanceling", + "ProvisionerJobCanceled", + "ProvisionerJobFailed" + ] }, - "environment_variables": { - "type": "object", - "additionalProperties": { - "type": "string" - } + "codersdk.ProvisionerStorageMethod": { + "type": "string", + "enum": [ + "file" + ], + "x-enum-varnames": [ + "ProvisionerStorageMethodFile" + ] }, - "expanded_directory": { - "type": "string" + "codersdk.PutExtendWorkspaceRequest": { + "type": "object", + "required": [ + "deadline" + ], + "properties": { + "deadline": { + "type": "string", + "format": "date-time" + } + } }, - "first_connected_at": { - "type": "string", - "format": "date-time" + "codersdk.RateLimitConfig": { + "type": "object", + "properties": { + "api": { + "type": "integer" + }, + "disable_all": { + "type": "boolean" + } + } }, - "id": { - "type": "string", - "format": "uuid" + "codersdk.Replica": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt is the timestamp when the replica was first seen.", + "type": "string", + "format": "date-time" + }, + "database_latency": { + "description": "DatabaseLatency is the latency in microseconds to the database.", + "type": "integer" + }, + "error": { + "description": "Error is the replica error.", + "type": "string" + }, + "hostname": { + "description": "Hostname is the hostname of the replica.", + "type": "string" + }, + "id": { + "description": "ID is the unique identifier for the replica.", + "type": "string", + "format": "uuid" + }, + "region_id": { + "description": "RegionID is the region of the replica.", + "type": "integer" + }, + "relay_address": { + "description": "RelayAddress is the accessible address to relay DERP connections.", + "type": "string" + } + } + }, + "codersdk.ResourceType": { + "type": "string", + "enum": [ + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "api_key", + "group", + "license" + ], + "x-enum-varnames": [ + "ResourceTypeTemplate", + "ResourceTypeTemplateVersion", + "ResourceTypeUser", + "ResourceTypeWorkspace", + "ResourceTypeWorkspaceBuild", + "ResourceTypeGitSSHKey", + "ResourceTypeAPIKey", + "ResourceTypeGroup", + "ResourceTypeLicense" + ] + }, + "codersdk.Response": { + "type": "object", + "properties": { + "detail": { + "description": "Detail is a debug message that provides further insight into why the\naction failed. This information can be technical and a regular golang\nerr.Error() text.\n- \"database: too many open connections\"\n- \"stat: too many open files\"", + "type": "string" + }, + "message": { + "description": "Message is an actionable message that depicts actions the request took.\nThese messages should be fully formed sentences with proper punctuation.\nExamples:\n- \"A user has been created.\"\n- \"Failed to create a user.\"", + "type": "string" + }, + "validations": { + "description": "Validations are form field-specific friendly error messages. They will be\nshown on a form field in the UI. These can also be used to add additional\ncontext if there is a set of errors in the primary 'Message'.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ValidationError" + } + } + } + }, + "codersdk.Role": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } }, - "instance_id": { - "type": "string" + "codersdk.SSHConfig": { + "type": "object", + "properties": { + "deploymentName": { + "description": "DeploymentName is the config-ssh Hostname prefix", + "type": "string" + }, + "sshconfigOptions": { + "description": "SSHConfigOptions are additional options to add to the ssh config file.\nThis will override defaults.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.SSHConfigResponse": { + "type": "object", + "properties": { + "hostname_prefix": { + "type": "string" + }, + "ssh_config_options": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "codersdk.ServiceBannerConfig": { + "type": "object", + "properties": { + "background_color": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "message": { + "type": "string" + } + } + }, + "codersdk.SessionCountDeploymentStats": { + "type": "object", + "properties": { + "jetbrains": { + "type": "integer" + }, + "reconnecting_pty": { + "type": "integer" + }, + "ssh": { + "type": "integer" + }, + "vscode": { + "type": "integer" + } + } + }, + "codersdk.SupportConfig": { + "type": "object", + "properties": { + "links": { + "$ref": "#/definitions/clibase.Struct-array_codersdk_LinkConfig" + } + } }, - "last_connected_at": { - "type": "string", - "format": "date-time" + "codersdk.SwaggerConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + } + } }, - "latency": { - "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.DERPRegion" - } + "codersdk.TLSConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/clibase.HostPort" + }, + "cert_file": { + "type": "array", + "items": { + "type": "string" + } + }, + "client_auth": { + "type": "string" + }, + "client_ca_file": { + "type": "string" + }, + "client_cert_file": { + "type": "string" + }, + "client_key_file": { + "type": "string" + }, + "enable": { + "type": "boolean" + }, + "key_file": { + "type": "array", + "items": { + "type": "string" + } + }, + "min_version": { + "type": "string" + }, + "redirect_http": { + "type": "boolean" + } + } + }, + "codersdk.TelemetryConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "trace": { + "type": "boolean" + }, + "url": { + "$ref": "#/definitions/clibase.URL" + } + } + }, + "codersdk.Template": { + "type": "object", + "properties": { + "active_user_count": { + "description": "ActiveUserCount is set to -1 when loading.", + "type": "integer" + }, + "active_version_id": { + "type": "string", + "format": "uuid" + }, + "allow_user_cancel_workspace_jobs": { + "type": "boolean" + }, + "build_time_stats": { + "$ref": "#/definitions/codersdk.TemplateBuildTimeStats" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by_id": { + "type": "string", + "format": "uuid" + }, + "created_by_name": { + "type": "string" + }, + "default_ttl_ms": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "max_ttl_ms": { + "description": "MaxTTLMillis is an enterprise feature. It's value is only used if your\nlicense is entitled to use the advanced template scheduling feature.", + "type": "integer" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "provisioner": { + "type": "string", + "enum": [ + "terraform" + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.TemplateBuildTimeStats": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TransitionStats" + } }, - "lifecycle_state": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" + "codersdk.TemplateDAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + } + } }, - "login_before_ready": { - "description": "LoginBeforeReady if true, the agent will delay logins until it is ready (e.g. executing startup script has ended).", - "type": "boolean" + "codersdk.TemplateExample": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "markdown": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, + "codersdk.TemplateRole": { + "type": "string", + "enum": [ + "admin", + "use", + "" + ], + "x-enum-varnames": [ + "TemplateRoleAdmin", + "TemplateRoleUse", + "TemplateRoleDeleted" + ] }, - "name": { - "type": "string" + "codersdk.TemplateUser": { + "type": "object", + "required": [ + "created_at", + "email", + "id", + "username" + ], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "role": { + "enum": [ + "admin", + "use" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateRole" + } + ] + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "status": { + "enum": [ + "active", + "suspended" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" + } + ] + }, + "username": { + "type": "string" + } + } + }, + "codersdk.TemplateVersion": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by": { + "$ref": "#/definitions/codersdk.User" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "readme": { + "type": "string" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.TemplateVersionGitAuth": { + "type": "object", + "properties": { + "authenticate_url": { + "type": "string" + }, + "authenticated": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/codersdk.GitProvider" + } + } + }, + "codersdk.TemplateVersionParameter": { + "type": "object", + "properties": { + "default_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "description_plaintext": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "legacy_variable_name": { + "type": "string" + }, + "mutable": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" + } + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "bool", + "list(string)" + ] + }, + "validation_error": { + "type": "string" + }, + "validation_max": { + "type": "integer" + }, + "validation_min": { + "type": "integer" + }, + "validation_monotonic": { + "enum": [ + "increasing", + "decreasing" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ValidationMonotonicOrder" + } + ] + }, + "validation_regex": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionParameterOption": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionVariable": { + "type": "object", + "properties": { + "default_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "required": { + "type": "boolean" + }, + "sensitive": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": [ + "string", + "number", + "bool" + ] + }, + "value": { + "type": "string" + } + } + }, + "codersdk.TokenConfig": { + "type": "object", + "properties": { + "max_token_lifetime": { + "type": "integer" + } + } }, - "operating_system": { - "type": "string" + "codersdk.TraceConfig": { + "type": "object", + "properties": { + "capture_logs": { + "type": "boolean" + }, + "enable": { + "type": "boolean" + }, + "honeycomb_api_key": { + "type": "string" + } + } + }, + "codersdk.TransitionStats": { + "type": "object", + "properties": { + "p50": { + "type": "integer", + "example": 123 + }, + "p95": { + "type": "integer", + "example": 146 + } + } }, - "resource_id": { - "type": "string", - "format": "uuid" + "codersdk.UpdateActiveTemplateVersion": { + "type": "object", + "required": [ + "id" + ], + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + } }, - "shutdown_script": { - "type": "string" + "codersdk.UpdateAppearanceConfig": { + "type": "object", + "properties": { + "logo_url": { + "type": "string" + }, + "service_banner": { + "$ref": "#/definitions/codersdk.ServiceBannerConfig" + } + } }, - "shutdown_script_timeout_seconds": { - "type": "integer" + "codersdk.UpdateCheckResponse": { + "type": "object", + "properties": { + "current": { + "description": "Current indicates whether the server version is the same as the latest.", + "type": "boolean" + }, + "url": { + "description": "URL to download the latest release of Coder.", + "type": "string" + }, + "version": { + "description": "Version is the semantic version for the latest release of Coder.", + "type": "string" + } + } + }, + "codersdk.UpdateRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } }, - "startup_script": { - "type": "string" + "codersdk.UpdateTemplateACL": { + "type": "object", + "properties": { + "group_perms": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TemplateRole" + } + }, + "user_perms": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TemplateRole" + } + } + } + }, + "codersdk.UpdateUserPasswordRequest": { + "type": "object", + "required": [ + "password" + ], + "properties": { + "old_password": { + "type": "string" + }, + "password": { + "type": "string" + } + } }, - "startup_script_timeout_seconds": { - "description": "StartupScriptTimeoutSeconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout.", - "type": "integer" + "codersdk.UpdateUserProfileRequest": { + "type": "object", + "required": [ + "username" + ], + "properties": { + "username": { + "type": "string" + } + } }, - "status": { - "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" + "codersdk.UpdateWorkspaceAutostartRequest": { + "type": "object", + "properties": { + "schedule": { + "type": "string" + } + } }, - "troubleshooting_url": { - "type": "string" + "codersdk.UpdateWorkspaceRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } }, - "updated_at": { - "type": "string", - "format": "date-time" + "codersdk.UpdateWorkspaceTTLRequest": { + "type": "object", + "properties": { + "ttl_ms": { + "type": "integer" + } + } }, - "version": { - "type": "string" - } - } - }, - "codersdk.WorkspaceAgentConnectionInfo": { - "type": "object", - "properties": { - "derp_map": { - "$ref": "#/definitions/tailcfg.DERPMap" - } - } - }, - "codersdk.WorkspaceAgentLifecycle": { - "type": "string", - "enum": [ - "created", - "starting", - "start_timeout", - "start_error", - "ready", - "shutting_down", - "shutdown_timeout", - "shutdown_error", - "off" - ], - "x-enum-varnames": [ - "WorkspaceAgentLifecycleCreated", - "WorkspaceAgentLifecycleStarting", - "WorkspaceAgentLifecycleStartTimeout", - "WorkspaceAgentLifecycleStartError", - "WorkspaceAgentLifecycleReady", - "WorkspaceAgentLifecycleShuttingDown", - "WorkspaceAgentLifecycleShutdownTimeout", - "WorkspaceAgentLifecycleShutdownError", - "WorkspaceAgentLifecycleOff" - ] - }, - "codersdk.WorkspaceAgentListeningPort": { - "type": "object", - "properties": { - "network": { - "description": "only \"tcp\" at the moment", - "type": "string" - }, - "port": { - "type": "integer" - }, - "process_name": { - "description": "may be empty", - "type": "string" - } - } - }, - "codersdk.WorkspaceAgentListeningPortsResponse": { - "type": "object", - "properties": { - "ports": { - "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPort" - } - } - } - }, - "codersdk.WorkspaceAgentStatus": { - "type": "string", - "enum": ["connecting", "connected", "disconnected", "timeout"], - "x-enum-varnames": [ - "WorkspaceAgentConnecting", - "WorkspaceAgentConnected", - "WorkspaceAgentDisconnected", - "WorkspaceAgentTimeout" - ] - }, - "codersdk.WorkspaceApp": { - "type": "object", - "properties": { - "command": { - "type": "string" - }, - "display_name": { - "description": "DisplayName is a friendly name for the app.", - "type": "string" - }, - "external": { - "description": "External specifies whether the URL should be opened externally on\nthe client or not.", - "type": "boolean" - }, - "health": { - "$ref": "#/definitions/codersdk.WorkspaceAppHealth" - }, - "healthcheck": { - "description": "Healthcheck specifies the configuration for checking app health.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.Healthcheck" - } - ] - }, - "icon": { - "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "sharing_level": { - "enum": ["owner", "authenticated", "public"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAppSharingLevel" - } - ] - }, - "slug": { - "description": "Slug is a unique identifier within the agent.", - "type": "string" - }, - "subdomain": { - "description": "Subdomain denotes whether the app should be accessed via a path on the\n`coder server` or via a hostname-based dev URL. If this is set to true\nand there is no app wildcard configured on the server, the app will not\nbe accessible in the UI.", - "type": "boolean" - }, - "url": { - "description": "URL is the address being proxied to inside the workspace.\nIf external is specified, this will be opened on the client.", - "type": "string" - } - } - }, - "codersdk.WorkspaceAppHealth": { - "type": "string", - "enum": ["disabled", "initializing", "healthy", "unhealthy"], - "x-enum-varnames": [ - "WorkspaceAppHealthDisabled", - "WorkspaceAppHealthInitializing", - "WorkspaceAppHealthHealthy", - "WorkspaceAppHealthUnhealthy" - ] - }, - "codersdk.WorkspaceAppSharingLevel": { - "type": "string", - "enum": ["owner", "authenticated", "public"], - "x-enum-varnames": [ - "WorkspaceAppSharingLevelOwner", - "WorkspaceAppSharingLevelAuthenticated", - "WorkspaceAppSharingLevelPublic" - ] - }, - "codersdk.WorkspaceBuild": { - "type": "object", - "properties": { - "build_number": { - "type": "integer" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "daily_cost": { - "type": "integer" - }, - "deadline": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "initiator_id": { - "type": "string", - "format": "uuid" - }, - "initiator_name": { - "type": "string" - }, - "job": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - }, - "max_deadline": { - "type": "string", - "format": "date-time" - }, - "reason": { - "enum": ["initiator", "autostart", "autostop"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.BuildReason" - } - ] - }, - "resources": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - }, - "status": { - "enum": [ - "pending", - "starting", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleting", - "deleted" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceStatus" - } - ] - }, - "template_version_id": { - "type": "string", - "format": "uuid" - }, - "template_version_name": { - "type": "string" - }, - "transition": { - "enum": ["start", "stop", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "workspace_id": { - "type": "string", - "format": "uuid" - }, - "workspace_name": { - "type": "string" - }, - "workspace_owner_id": { - "type": "string", - "format": "uuid" - }, - "workspace_owner_name": { - "type": "string" - } - } - }, - "codersdk.WorkspaceBuildParameter": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.WorkspaceConnectionLatencyMS": { - "type": "object", - "properties": { - "p50": { - "type": "number" - }, - "p95": { - "type": "number" - } - } - }, - "codersdk.WorkspaceDeploymentStats": { - "type": "object", - "properties": { - "building": { - "type": "integer" + "codersdk.UploadResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "format": "uuid" + } + } }, - "connection_latency_ms": { - "$ref": "#/definitions/codersdk.WorkspaceConnectionLatencyMS" + "codersdk.User": { + "type": "object", + "required": [ + "created_at", + "email", + "id", + "username" + ], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "status": { + "enum": [ + "active", + "suspended" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" + } + ] + }, + "username": { + "type": "string" + } + } + }, + "codersdk.UserStatus": { + "type": "string", + "enum": [ + "active", + "suspended" + ], + "x-enum-varnames": [ + "UserStatusActive", + "UserStatusSuspended" + ] }, - "failed": { - "type": "integer" + "codersdk.ValidationError": { + "type": "object", + "required": [ + "detail", + "field" + ], + "properties": { + "detail": { + "type": "string" + }, + "field": { + "type": "string" + } + } }, - "pending": { - "type": "integer" + "codersdk.ValidationMonotonicOrder": { + "type": "string", + "enum": [ + "increasing", + "decreasing" + ], + "x-enum-varnames": [ + "MonotonicOrderIncreasing", + "MonotonicOrderDecreasing" + ] }, - "running": { - "type": "integer" + "codersdk.VariableValue": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } }, - "rx_bytes": { - "type": "integer" + "codersdk.Workspace": { + "type": "object", + "properties": { + "autostart_schedule": { + "type": "string" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_used_at": { + "type": "string", + "format": "date-time" + }, + "latest_build": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "outdated": { + "type": "boolean" + }, + "owner_id": { + "type": "string", + "format": "uuid" + }, + "owner_name": { + "type": "string" + }, + "template_allow_user_cancel_workspace_jobs": { + "type": "boolean" + }, + "template_display_name": { + "type": "string" + }, + "template_icon": { + "type": "string" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "template_name": { + "type": "string" + }, + "ttl_ms": { + "type": "integer" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.WorkspaceAgent": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } + }, + "architecture": { + "type": "string" + }, + "connection_timeout_seconds": { + "type": "integer" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "directory": { + "type": "string" + }, + "disconnected_at": { + "type": "string", + "format": "date-time" + }, + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "expanded_directory": { + "type": "string" + }, + "first_connected_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "instance_id": { + "type": "string" + }, + "last_connected_at": { + "type": "string", + "format": "date-time" + }, + "latency": { + "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.DERPRegion" + } + }, + "lifecycle_state": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" + }, + "login_before_ready": { + "description": "LoginBeforeReady if true, the agent will delay logins until it is ready (e.g. executing startup script has ended).", + "type": "boolean" + }, + "name": { + "type": "string" + }, + "operating_system": { + "type": "string" + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "shutdown_script": { + "type": "string" + }, + "shutdown_script_timeout_seconds": { + "type": "integer" + }, + "startup_script": { + "type": "string" + }, + "startup_script_timeout_seconds": { + "description": "StartupScriptTimeoutSeconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout.", + "type": "integer" + }, + "status": { + "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" + }, + "troubleshooting_url": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "version": { + "type": "string" + } + } + }, + "codersdk.WorkspaceAgentConnectionInfo": { + "type": "object", + "properties": { + "derp_map": { + "$ref": "#/definitions/tailcfg.DERPMap" + } + } }, - "stopped": { - "type": "integer" + "codersdk.WorkspaceAgentLifecycle": { + "type": "string", + "enum": [ + "created", + "starting", + "start_timeout", + "start_error", + "ready", + "shutting_down", + "shutdown_timeout", + "shutdown_error", + "off" + ], + "x-enum-varnames": [ + "WorkspaceAgentLifecycleCreated", + "WorkspaceAgentLifecycleStarting", + "WorkspaceAgentLifecycleStartTimeout", + "WorkspaceAgentLifecycleStartError", + "WorkspaceAgentLifecycleReady", + "WorkspaceAgentLifecycleShuttingDown", + "WorkspaceAgentLifecycleShutdownTimeout", + "WorkspaceAgentLifecycleShutdownError", + "WorkspaceAgentLifecycleOff" + ] + }, + "codersdk.WorkspaceAgentListeningPort": { + "type": "object", + "properties": { + "network": { + "description": "only \"tcp\" at the moment", + "type": "string" + }, + "port": { + "type": "integer" + }, + "process_name": { + "description": "may be empty", + "type": "string" + } + } + }, + "codersdk.WorkspaceAgentListeningPortsResponse": { + "type": "object", + "properties": { + "ports": { + "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPort" + } + } + } }, - "tx_bytes": { - "type": "integer" - } - } - }, - "codersdk.WorkspaceQuota": { - "type": "object", - "properties": { - "budget": { - "type": "integer" - }, - "credits_consumed": { - "type": "integer" - } - } - }, - "codersdk.WorkspaceResource": { - "type": "object", - "properties": { - "agents": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgent" - } - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "daily_cost": { - "type": "integer" - }, - "hide": { - "type": "boolean" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job_id": { - "type": "string", - "format": "uuid" - }, - "metadata": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResourceMetadata" - } - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - }, - "workspace_transition": { - "enum": ["start", "stop", "delete"], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - } - } - }, - "codersdk.WorkspaceResourceMetadata": { - "type": "object", - "properties": { - "key": { - "type": "string" + "codersdk.WorkspaceAgentStatus": { + "type": "string", + "enum": [ + "connecting", + "connected", + "disconnected", + "timeout" + ], + "x-enum-varnames": [ + "WorkspaceAgentConnecting", + "WorkspaceAgentConnected", + "WorkspaceAgentDisconnected", + "WorkspaceAgentTimeout" + ] + }, + "codersdk.WorkspaceApp": { + "type": "object", + "properties": { + "command": { + "type": "string" + }, + "display_name": { + "description": "DisplayName is a friendly name for the app.", + "type": "string" + }, + "external": { + "description": "External specifies whether the URL should be opened externally on\nthe client or not.", + "type": "boolean" + }, + "health": { + "$ref": "#/definitions/codersdk.WorkspaceAppHealth" + }, + "healthcheck": { + "description": "Healthcheck specifies the configuration for checking app health.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.Healthcheck" + } + ] + }, + "icon": { + "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "sharing_level": { + "enum": [ + "owner", + "authenticated", + "public" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAppSharingLevel" + } + ] + }, + "slug": { + "description": "Slug is a unique identifier within the agent.", + "type": "string" + }, + "subdomain": { + "description": "Subdomain denotes whether the app should be accessed via a path on the\n`coder server` or via a hostname-based dev URL. If this is set to true\nand there is no app wildcard configured on the server, the app will not\nbe accessible in the UI.", + "type": "boolean" + }, + "url": { + "description": "URL is the address being proxied to inside the workspace.\nIf external is specified, this will be opened on the client.", + "type": "string" + } + } + }, + "codersdk.WorkspaceAppHealth": { + "type": "string", + "enum": [ + "disabled", + "initializing", + "healthy", + "unhealthy" + ], + "x-enum-varnames": [ + "WorkspaceAppHealthDisabled", + "WorkspaceAppHealthInitializing", + "WorkspaceAppHealthHealthy", + "WorkspaceAppHealthUnhealthy" + ] }, - "sensitive": { - "type": "boolean" + "codersdk.WorkspaceAppSharingLevel": { + "type": "string", + "enum": [ + "owner", + "authenticated", + "public" + ], + "x-enum-varnames": [ + "WorkspaceAppSharingLevelOwner", + "WorkspaceAppSharingLevelAuthenticated", + "WorkspaceAppSharingLevelPublic" + ] }, - "value": { - "type": "string" - } - } - }, - "codersdk.WorkspaceStatus": { - "type": "string", - "enum": [ - "pending", - "starting", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleting", - "deleted" - ], - "x-enum-varnames": [ - "WorkspaceStatusPending", - "WorkspaceStatusStarting", - "WorkspaceStatusRunning", - "WorkspaceStatusStopping", - "WorkspaceStatusStopped", - "WorkspaceStatusFailed", - "WorkspaceStatusCanceling", - "WorkspaceStatusCanceled", - "WorkspaceStatusDeleting", - "WorkspaceStatusDeleted" - ] - }, - "codersdk.WorkspaceTransition": { - "type": "string", - "enum": ["start", "stop", "delete"], - "x-enum-varnames": [ - "WorkspaceTransitionStart", - "WorkspaceTransitionStop", - "WorkspaceTransitionDelete" - ] - }, - "codersdk.WorkspacesResponse": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - }, - "database.ParameterDestinationScheme": { - "type": "string", - "enum": ["none", "environment_variable", "provisioner_variable"], - "x-enum-varnames": [ - "ParameterDestinationSchemeNone", - "ParameterDestinationSchemeEnvironmentVariable", - "ParameterDestinationSchemeProvisionerVariable" - ] - }, - "database.ParameterScope": { - "type": "string", - "enum": ["template", "import_job", "workspace"], - "x-enum-varnames": [ - "ParameterScopeTemplate", - "ParameterScopeImportJob", - "ParameterScopeWorkspace" - ] - }, - "database.ParameterSourceScheme": { - "type": "string", - "enum": ["none", "data"], - "x-enum-varnames": [ - "ParameterSourceSchemeNone", - "ParameterSourceSchemeData" - ] - }, - "parameter.ComputedValue": { - "type": "object", - "properties": { - "created_at": { - "type": "string" + "codersdk.WorkspaceBuild": { + "type": "object", + "properties": { + "build_number": { + "type": "integer" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "daily_cost": { + "type": "integer" + }, + "deadline": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "initiator_id": { + "type": "string", + "format": "uuid" + }, + "initiator_name": { + "type": "string" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "max_deadline": { + "type": "string", + "format": "date-time" + }, + "reason": { + "enum": [ + "initiator", + "autostart", + "autostop" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.BuildReason" + } + ] + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + }, + "status": { + "enum": [ + "pending", + "starting", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleting", + "deleted" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceStatus" + } + ] + }, + "template_version_id": { + "type": "string", + "format": "uuid" + }, + "template_version_name": { + "type": "string" + }, + "transition": { + "enum": [ + "start", + "stop", + "delete" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "workspace_id": { + "type": "string", + "format": "uuid" + }, + "workspace_name": { + "type": "string" + }, + "workspace_owner_id": { + "type": "string", + "format": "uuid" + }, + "workspace_owner_name": { + "type": "string" + } + } + }, + "codersdk.WorkspaceBuildParameter": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } }, - "default_source_value": { - "type": "boolean" + "codersdk.WorkspaceConnectionLatencyMS": { + "type": "object", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + } + } }, - "destination_scheme": { - "$ref": "#/definitions/database.ParameterDestinationScheme" + "codersdk.WorkspaceDeploymentStats": { + "type": "object", + "properties": { + "building": { + "type": "integer" + }, + "connection_latency_ms": { + "$ref": "#/definitions/codersdk.WorkspaceConnectionLatencyMS" + }, + "failed": { + "type": "integer" + }, + "pending": { + "type": "integer" + }, + "running": { + "type": "integer" + }, + "rx_bytes": { + "type": "integer" + }, + "stopped": { + "type": "integer" + }, + "tx_bytes": { + "type": "integer" + } + } + }, + "codersdk.WorkspaceQuota": { + "type": "object", + "properties": { + "budget": { + "type": "integer" + }, + "credits_consumed": { + "type": "integer" + } + } }, - "id": { - "type": "string" + "codersdk.WorkspaceResource": { + "type": "object", + "properties": { + "agents": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "daily_cost": { + "type": "integer" + }, + "hide": { + "type": "boolean" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "metadata": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResourceMetadata" + } + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "workspace_transition": { + "enum": [ + "start", + "stop", + "delete" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + } + } + }, + "codersdk.WorkspaceResourceMetadata": { + "type": "object", + "properties": { + "key": { + "type": "string" + }, + "sensitive": { + "type": "boolean" + }, + "value": { + "type": "string" + } + } }, - "name": { - "type": "string" + "codersdk.WorkspaceStatus": { + "type": "string", + "enum": [ + "pending", + "starting", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleting", + "deleted" + ], + "x-enum-varnames": [ + "WorkspaceStatusPending", + "WorkspaceStatusStarting", + "WorkspaceStatusRunning", + "WorkspaceStatusStopping", + "WorkspaceStatusStopped", + "WorkspaceStatusFailed", + "WorkspaceStatusCanceling", + "WorkspaceStatusCanceled", + "WorkspaceStatusDeleting", + "WorkspaceStatusDeleted" + ] + }, + "codersdk.WorkspaceTransition": { + "type": "string", + "enum": [ + "start", + "stop", + "delete" + ], + "x-enum-varnames": [ + "WorkspaceTransitionStart", + "WorkspaceTransitionStop", + "WorkspaceTransitionDelete" + ] }, - "schema_id": { - "type": "string" + "codersdk.WorkspacesResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } }, - "scope": { - "$ref": "#/definitions/database.ParameterScope" + "database.ParameterDestinationScheme": { + "type": "string", + "enum": [ + "none", + "environment_variable", + "provisioner_variable" + ], + "x-enum-varnames": [ + "ParameterDestinationSchemeNone", + "ParameterDestinationSchemeEnvironmentVariable", + "ParameterDestinationSchemeProvisionerVariable" + ] }, - "scope_id": { - "type": "string" + "database.ParameterScope": { + "type": "string", + "enum": [ + "template", + "import_job", + "workspace" + ], + "x-enum-varnames": [ + "ParameterScopeTemplate", + "ParameterScopeImportJob", + "ParameterScopeWorkspace" + ] }, - "source_scheme": { - "$ref": "#/definitions/database.ParameterSourceScheme" + "database.ParameterSourceScheme": { + "type": "string", + "enum": [ + "none", + "data" + ], + "x-enum-varnames": [ + "ParameterSourceSchemeNone", + "ParameterSourceSchemeData" + ] }, - "source_value": { - "type": "string" + "parameter.ComputedValue": { + "type": "object", + "properties": { + "created_at": { + "type": "string" + }, + "default_source_value": { + "type": "boolean" + }, + "destination_scheme": { + "$ref": "#/definitions/database.ParameterDestinationScheme" + }, + "id": { + "type": "string" + }, + "name": { + "type": "string" + }, + "schema_id": { + "type": "string" + }, + "scope": { + "$ref": "#/definitions/database.ParameterScope" + }, + "scope_id": { + "type": "string" + }, + "source_scheme": { + "$ref": "#/definitions/database.ParameterSourceScheme" + }, + "source_value": { + "type": "string" + }, + "updated_at": { + "type": "string" + } + } + }, + "sql.NullTime": { + "type": "object", + "properties": { + "time": { + "type": "string" + }, + "valid": { + "description": "Valid is true if Time is not NULL", + "type": "boolean" + } + } }, - "updated_at": { - "type": "string" - } - } - }, - "sql.NullTime": { - "type": "object", - "properties": { - "time": { - "type": "string" - }, - "valid": { - "description": "Valid is true if Time is not NULL", - "type": "boolean" - } - } - }, - "tailcfg.DERPMap": { - "type": "object", - "properties": { - "omitDefaultRegions": { - "description": "OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those\nspecified in this DERPMap. If there are none set outside of the defaults, this is a noop.", - "type": "boolean" - }, - "regions": { - "description": "Regions is the set of geographic regions running DERP node(s).\n\nIt's keyed by the DERPRegion.RegionID.\n\nThe numbers are not necessarily contiguous.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/tailcfg.DERPRegion" - } - } - } - }, - "tailcfg.DERPNode": { - "type": "object", - "properties": { - "certName": { - "description": "CertName optionally specifies the expected TLS cert common\nname. If empty, HostName is used. If CertName is non-empty,\nHostName is only used for the TCP dial (if IPv4/IPv6 are\nnot present) + TLS ClientHello.", - "type": "string" - }, - "derpport": { - "description": "DERPPort optionally provides an alternate TLS port number\nfor the DERP HTTPS server.\n\nIf zero, 443 is used.", - "type": "integer" - }, - "forceHTTP": { - "description": "ForceHTTP is used by unit tests to force HTTP.\nIt should not be set by users.", - "type": "boolean" - }, - "hostName": { - "description": "HostName is the DERP node's hostname.\n\nIt is required but need not be unique; multiple nodes may\nhave the same HostName but vary in configuration otherwise.", - "type": "string" - }, - "insecureForTests": { - "description": "InsecureForTests is used by unit tests to disable TLS verification.\nIt should not be set by users.", - "type": "boolean" - }, - "ipv4": { - "description": "IPv4 optionally forces an IPv4 address to use, instead of using DNS.\nIf empty, A record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv4 address, IPv4 is not used; the\nconventional string to disable IPv4 (and not use DNS) is\n\"none\".", - "type": "string" - }, - "ipv6": { - "description": "IPv6 optionally forces an IPv6 address to use, instead of using DNS.\nIf empty, AAAA record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv6 address, IPv6 is not used; the\nconventional string to disable IPv6 (and not use DNS) is\n\"none\".", - "type": "string" - }, - "name": { - "description": "Name is a unique node name (across all regions).\nIt is not a host name.\nIt's typically of the form \"1b\", \"2a\", \"3b\", etc. (region\nID + suffix within that region)", - "type": "string" - }, - "regionID": { - "description": "RegionID is the RegionID of the DERPRegion that this node\nis running in.", - "type": "integer" - }, - "stunonly": { - "description": "STUNOnly marks a node as only a STUN server and not a DERP\nserver.", - "type": "boolean" - }, - "stunport": { - "description": "Port optionally specifies a STUN port to use.\nZero means 3478.\nTo disable STUN on this node, use -1.", - "type": "integer" - }, - "stuntestIP": { - "description": "STUNTestIP is used in tests to override the STUN server's IP.\nIf empty, it's assumed to be the same as the DERP server.", - "type": "string" - } - } - }, - "tailcfg.DERPRegion": { - "type": "object", - "properties": { - "avoid": { - "description": "Avoid is whether the client should avoid picking this as its home\nregion. The region should only be used if a peer is there.\nClients already using this region as their home should migrate\naway to a new region without Avoid set.", - "type": "boolean" - }, - "embeddedRelay": { - "description": "EmbeddedRelay is true when the region is bundled with the Coder\ncontrol plane.", - "type": "boolean" - }, - "nodes": { - "description": "Nodes are the DERP nodes running in this region, in\npriority order for the current client. Client TLS\nconnections should ideally only go to the first entry\n(falling back to the second if necessary). STUN packets\nshould go to the first 1 or 2.\n\nIf nodes within a region route packets amongst themselves,\nbut not to other regions. That said, each user/domain\nshould get a the same preferred node order, so if all nodes\nfor a user/network pick the first one (as they should, when\nthings are healthy), the inter-cluster routing is minimal\nto zero.", - "type": "array", - "items": { - "$ref": "#/definitions/tailcfg.DERPNode" - } - }, - "regionCode": { - "description": "RegionCode is a short name for the region. It's usually a popular\ncity or airport code in the region: \"nyc\", \"sf\", \"sin\",\n\"fra\", etc.", - "type": "string" - }, - "regionID": { - "description": "RegionID is a unique integer for a geographic region.\n\nIt corresponds to the legacy derpN.tailscale.com hostnames\nused by older clients. (Older clients will continue to resolve\nderpN.tailscale.com when contacting peers, rather than use\nthe server-provided DERPMap)\n\nRegionIDs must be non-zero, positive, and guaranteed to fit\nin a JavaScript number.\n\nRegionIDs in range 900-999 are reserved for end users to run their\nown DERP nodes.", - "type": "integer" - }, - "regionName": { - "description": "RegionName is a long English name for the region: \"New York City\",\n\"San Francisco\", \"Singapore\", \"Frankfurt\", etc.", - "type": "string" + "tailcfg.DERPMap": { + "type": "object", + "properties": { + "omitDefaultRegions": { + "description": "OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those\nspecified in this DERPMap. If there are none set outside of the defaults, this is a noop.", + "type": "boolean" + }, + "regions": { + "description": "Regions is the set of geographic regions running DERP node(s).\n\nIt's keyed by the DERPRegion.RegionID.\n\nThe numbers are not necessarily contiguous.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/tailcfg.DERPRegion" + } + } + } + }, + "tailcfg.DERPNode": { + "type": "object", + "properties": { + "certName": { + "description": "CertName optionally specifies the expected TLS cert common\nname. If empty, HostName is used. If CertName is non-empty,\nHostName is only used for the TCP dial (if IPv4/IPv6 are\nnot present) + TLS ClientHello.", + "type": "string" + }, + "derpport": { + "description": "DERPPort optionally provides an alternate TLS port number\nfor the DERP HTTPS server.\n\nIf zero, 443 is used.", + "type": "integer" + }, + "forceHTTP": { + "description": "ForceHTTP is used by unit tests to force HTTP.\nIt should not be set by users.", + "type": "boolean" + }, + "hostName": { + "description": "HostName is the DERP node's hostname.\n\nIt is required but need not be unique; multiple nodes may\nhave the same HostName but vary in configuration otherwise.", + "type": "string" + }, + "insecureForTests": { + "description": "InsecureForTests is used by unit tests to disable TLS verification.\nIt should not be set by users.", + "type": "boolean" + }, + "ipv4": { + "description": "IPv4 optionally forces an IPv4 address to use, instead of using DNS.\nIf empty, A record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv4 address, IPv4 is not used; the\nconventional string to disable IPv4 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "ipv6": { + "description": "IPv6 optionally forces an IPv6 address to use, instead of using DNS.\nIf empty, AAAA record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv6 address, IPv6 is not used; the\nconventional string to disable IPv6 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "name": { + "description": "Name is a unique node name (across all regions).\nIt is not a host name.\nIt's typically of the form \"1b\", \"2a\", \"3b\", etc. (region\nID + suffix within that region)", + "type": "string" + }, + "regionID": { + "description": "RegionID is the RegionID of the DERPRegion that this node\nis running in.", + "type": "integer" + }, + "stunonly": { + "description": "STUNOnly marks a node as only a STUN server and not a DERP\nserver.", + "type": "boolean" + }, + "stunport": { + "description": "Port optionally specifies a STUN port to use.\nZero means 3478.\nTo disable STUN on this node, use -1.", + "type": "integer" + }, + "stuntestIP": { + "description": "STUNTestIP is used in tests to override the STUN server's IP.\nIf empty, it's assumed to be the same as the DERP server.", + "type": "string" + } + } + }, + "tailcfg.DERPRegion": { + "type": "object", + "properties": { + "avoid": { + "description": "Avoid is whether the client should avoid picking this as its home\nregion. The region should only be used if a peer is there.\nClients already using this region as their home should migrate\naway to a new region without Avoid set.", + "type": "boolean" + }, + "embeddedRelay": { + "description": "EmbeddedRelay is true when the region is bundled with the Coder\ncontrol plane.", + "type": "boolean" + }, + "nodes": { + "description": "Nodes are the DERP nodes running in this region, in\npriority order for the current client. Client TLS\nconnections should ideally only go to the first entry\n(falling back to the second if necessary). STUN packets\nshould go to the first 1 or 2.\n\nIf nodes within a region route packets amongst themselves,\nbut not to other regions. That said, each user/domain\nshould get a the same preferred node order, so if all nodes\nfor a user/network pick the first one (as they should, when\nthings are healthy), the inter-cluster routing is minimal\nto zero.", + "type": "array", + "items": { + "$ref": "#/definitions/tailcfg.DERPNode" + } + }, + "regionCode": { + "description": "RegionCode is a short name for the region. It's usually a popular\ncity or airport code in the region: \"nyc\", \"sf\", \"sin\",\n\"fra\", etc.", + "type": "string" + }, + "regionID": { + "description": "RegionID is a unique integer for a geographic region.\n\nIt corresponds to the legacy derpN.tailscale.com hostnames\nused by older clients. (Older clients will continue to resolve\nderpN.tailscale.com when contacting peers, rather than use\nthe server-provided DERPMap)\n\nRegionIDs must be non-zero, positive, and guaranteed to fit\nin a JavaScript number.\n\nRegionIDs in range 900-999 are reserved for end users to run their\nown DERP nodes.", + "type": "integer" + }, + "regionName": { + "description": "RegionName is a long English name for the region: \"New York City\",\n\"San Francisco\", \"Singapore\", \"Frankfurt\", etc.", + "type": "string" + } + } + }, + "url.Userinfo": { + "type": "object" + } + }, + "securityDefinitions": { + "CoderSessionToken": { + "type": "apiKey", + "name": "Coder-Session-Token", + "in": "header" } - } - }, - "url.Userinfo": { - "type": "object" - } - }, - "securityDefinitions": { - "CoderSessionToken": { - "type": "apiKey", - "name": "Coder-Session-Token", - "in": "header" } - } -} +} \ No newline at end of file diff --git a/coderd/organizations.go b/coderd/organizations.go index ac7e61faa7275..13906baef63b3 100644 --- a/coderd/organizations.go +++ b/coderd/organizations.go @@ -24,7 +24,7 @@ import ( // @Param organization path string true "Organization ID" format(uuid) // @Success 200 {object} codersdk.Organization // @Router /organizations/{organization} [get] -func (API) organization(rw http.ResponseWriter, r *http.Request) { +func (*API) organization(rw http.ResponseWriter, r *http.Request) { ctx := r.Context() organization := httpmw.OrganizationParam(r) diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 7b2c7f7ba208c..1634b341b3162 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1002,6 +1002,7 @@ export interface Workspace { readonly updated_at: string readonly owner_id: string readonly owner_name: string + readonly organization_id: string readonly template_id: string readonly template_name: string readonly template_display_name: string From d038934e289b227f9df796bb002ff4dd3597db11 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 15:41:18 +0000 Subject: [PATCH 19/29] Make gen --- coderd/apidoc/swagger.json | 17511 +++++++++++++++++------------------ 1 file changed, 8311 insertions(+), 9200 deletions(-) diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index b180325de3318..074a6c4ab5ebc 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -1,9299 +1,8410 @@ { - "swagger": "2.0", - "info": { - "description": "Coderd is the service created by running coder server. It is a thin API that connects workspaces, provisioners and users. coderd stores its state in Postgres and is the only service that communicates with Postgres.", - "title": "Coder API", - "termsOfService": "https://coder.com/legal/terms-of-service", - "contact": { - "name": "API Support", - "url": "https://coder.com", - "email": "support@coder.com" + "swagger": "2.0", + "info": { + "description": "Coderd is the service created by running coder server. It is a thin API that connects workspaces, provisioners and users. coderd stores its state in Postgres and is the only service that communicates with Postgres.", + "title": "Coder API", + "termsOfService": "https://coder.com/legal/terms-of-service", + "contact": { + "name": "API Support", + "url": "https://coder.com", + "email": "support@coder.com" + }, + "license": { + "name": "AGPL-3.0", + "url": "https://github.com/coder/coder/blob/main/LICENSE" + }, + "version": "2.0" + }, + "basePath": "/api/v2", + "paths": { + "/": { + "get": { + "produces": ["application/json"], + "tags": ["General"], + "summary": "API root handler", + "operationId": "api-root-handler", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/appearance": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get appearance", + "operationId": "get-appearance", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AppearanceConfig" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update appearance", + "operationId": "update-appearance", + "parameters": [ + { + "description": "Update appearance request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" + } + } + } + } + }, + "/applications/auth-redirect": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Applications"], + "summary": "Redirect to URI with encrypted API key", + "operationId": "redirect-to-uri-with-encrypted-api-key", + "parameters": [ + { + "type": "string", + "description": "Redirect destination", + "name": "redirect_uri", + "in": "query" + } + ], + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/applications/host": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Applications"], + "summary": "Get applications host", + "operationId": "get-applications-host", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AppHostResponse" + } + } + } + } + }, + "/audit": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Audit"], + "summary": "Get audit logs", + "operationId": "get-audit-logs", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuditLogResponse" + } + } + } + } + }, + "/audit/testgenerate": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Audit"], + "summary": "Generate fake audit log", + "operationId": "generate-fake-audit-log", + "parameters": [ + { + "description": "Audit log request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/authcheck": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Authorization"], + "summary": "Check authorization", + "operationId": "check-authorization", + "parameters": [ + { + "description": "Authorization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AuthorizationRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthorizationResponse" + } + } + } + } + }, + "/buildinfo": { + "get": { + "produces": ["application/json"], + "tags": ["General"], + "summary": "Build info", + "operationId": "build-info", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.BuildInfoResponse" + } + } + } + } + }, + "/csp/reports": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["General"], + "summary": "Report CSP violations", + "operationId": "report-csp-violations", + "parameters": [ + { + "description": "Violation report", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.cspViolation" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/debug/coordinator": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["text/html"], + "tags": ["Debug"], + "summary": "Debug Info Wireguard Coordinator", + "operationId": "debug-info-wireguard-coordinator", + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/deployment/config": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get deployment config", + "operationId": "get-deployment-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentConfig" + } + } + } + } + }, + "/deployment/ssh": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "SSH Config", + "operationId": "ssh-config", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.SSHConfigResponse" + } + } + } + } + }, + "/deployment/stats": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get deployment stats", + "operationId": "get-deployment-stats", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentStats" + } + } + } + } + }, + "/entitlements": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get entitlements", + "operationId": "get-entitlements", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Entitlements" + } + } + } + } + }, + "/experiments": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get experiments", + "operationId": "get-experiments", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Experiment" + } + } + } + } + } + }, + "/files": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "Swagger notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", + "consumes": ["application/x-tar"], + "produces": ["application/json"], + "tags": ["Files"], + "summary": "Upload file", + "operationId": "upload-file", + "parameters": [ + { + "type": "string", + "default": "application/x-tar", + "description": "Content-Type must be `application/x-tar`", + "name": "Content-Type", + "in": "header", + "required": true + }, + { + "type": "file", + "description": "File to be uploaded", + "name": "file", + "in": "formData", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.UploadResponse" + } + } + } + } + }, + "/files/{fileID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Files"], + "summary": "Get file by ID", + "operationId": "get-file-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "File ID", + "name": "fileID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/groups": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get groups", + "operationId": "get-groups", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + } + }, + "/groups/{group}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get group by name", + "operationId": "get-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Delete group by name", + "operationId": "delete-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update group by name", + "operationId": "update-group-by-name", + "parameters": [ + { + "type": "string", + "description": "Group name", + "name": "group", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/insights/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Insights"], + "summary": "Get deployment DAUs", + "operationId": "get-deployment-daus", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.DeploymentDAUsResponse" + } + } + } + } + }, + "/licenses": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get licenses", + "operationId": "get-licenses", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.License" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Add new license", + "operationId": "add-new-license", + "parameters": [ + { + "description": "Add license request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.AddLicenseRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.License" + } + } + } + } + }, + "/licenses/{id}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Delete license", + "operationId": "delete-license", + "parameters": [ + { + "type": "string", + "format": "number", + "description": "License ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/organizations": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Create organization", + "operationId": "create-organization", + "parameters": [ + { + "description": "Create organization request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateOrganizationRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{organization}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Organizations"], + "summary": "Get organization by ID", + "operationId": "get-organization-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/organizations/{organization}/groups": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get groups by organization", + "operationId": "get-groups-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create group for organization", + "operationId": "create-group-for-organization", + "parameters": [ + { + "description": "Create group request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateGroupRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/organizations/{organization}/groups/{groupName}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get group by organization and group name", + "operationId": "get-group-by-organization-and-group-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Group name", + "name": "groupName", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Group" + } + } + } + } + }, + "/organizations/{organization}/members/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Get member roles by organization", + "operationId": "get-member-roles-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, + "/organizations/{organization}/members/{user}/roles": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Assign role to organization member", + "operationId": "assign-role-to-organization-member", + "parameters": [ + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.OrganizationMember" + } + } + } + } + }, + "/organizations/{organization}/members/{user}/workspaces": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Create user workspace by organization", + "operationId": "create-user-workspace-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Username, UUID, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create workspace request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/organizations/{organization}/provisionerdaemons": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get provisioner daemons", + "operationId": "get-provisioner-daemons", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerDaemon" + } + } + } + } + } + }, + "/organizations/{organization}/provisionerdaemons/serve": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Enterprise"], + "summary": "Serve provisioner daemon", + "operationId": "serve-provisioner-daemon", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/organizations/{organization}/templates": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get templates by organization", + "operationId": "get-templates-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create template by organization", + "operationId": "create-template-by-organization", + "parameters": [ + { + "description": "Request body", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateRequest" + } + }, + { + "type": "string", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/examples": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template examples by organization", + "operationId": "get-template-examples-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateExample" + } + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get templates by organization and template name", + "operationId": "get-templates-by-organization-and-template-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by organization, template, and name", + "operationId": "get-template-version-by-organization-template-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get previous template version by organization, template, and name", + "operationId": "get-previous-template-version-by-organization-template-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template name", + "name": "templatename", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/organizations/{organization}/templateversions": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create template version by organization", + "operationId": "create-template-version-by-organization", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Organization ID", + "name": "organization", + "in": "path", + "required": true + }, + { + "description": "Create template version request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/parameters/{scope}/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Parameters"], + "summary": "Get parameters", + "operationId": "get-parameters", + "parameters": [ + { + "enum": ["template", "workspace", "import_job"], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Parameter" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Parameters"], + "summary": "Create parameter", + "operationId": "create-parameter", + "parameters": [ + { + "description": "Parameter request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + { + "enum": ["template", "workspace", "import_job"], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.Parameter" + } + } + } + } + }, + "/parameters/{scope}/{id}/{name}": { + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Parameters"], + "summary": "Delete parameter", + "operationId": "delete-parameter", + "parameters": [ + { + "enum": ["template", "workspace", "import_job"], + "type": "string", + "description": "Scope", + "name": "scope", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "ID", + "name": "id", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Name", + "name": "name", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/replicas": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get active replicas", + "operationId": "get-active-replicas", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Replica" + } + } + } + } + } + }, + "/scim/v2/Users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Get users", + "operationId": "scim-get-users", + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Create new user", + "operationId": "scim-create-new-user", + "parameters": [ + { + "description": "New user", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + } + } + }, + "/scim/v2/Users/{id}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Get user by ID", + "operationId": "scim-get-user-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + } + ], + "responses": { + "404": { + "description": "Not Found" + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/scim+json"], + "tags": ["Enterprise"], + "summary": "SCIM 2.0: Update user account", + "operationId": "scim-update-user-status", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "User ID", + "name": "id", + "in": "path", + "required": true + }, + { + "description": "Update user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/coderd.SCIMUser" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/templates/{template}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template metadata by ID", + "operationId": "get-template-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Delete template by ID", + "operationId": "delete-template-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Update template metadata by ID", + "operationId": "update-template-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Template" + } + } + } + } + }, + "/templates/{template}/acl": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get template ACLs", + "operationId": "get-template-acls", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateUser" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Update template ACL", + "operationId": "update-template-acl", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "description": "Update template request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateTemplateACL" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/daus": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template DAUs by ID", + "operationId": "get-template-daus-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateDAUsResponse" + } + } + } + } + }, + "/templates/{template}/versions": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "List template versions by template ID", + "operationId": "list-template-versions-by-template-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Update active template version by template ID", + "operationId": "update-active-template-version-by-template-id", + "parameters": [ + { + "description": "Modified template version", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateActiveTemplateVersion" + } + }, + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templates/{template}/versions/{templateversionname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by template ID and name", + "operationId": "get-template-version-by-template-id-and-name", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template ID", + "name": "template", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Template version name", + "name": "templateversionname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + } + }, + "/templateversions/{templateversion}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version by ID", + "operationId": "get-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TemplateVersion" + } + } + } + } + }, + "/templateversions/{templateversion}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Cancel template version by ID", + "operationId": "cancel-template-version-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Create template version dry-run", + "operationId": "create-template-version-dry-run", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "description": "Dry-run request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version dry-run by job ID", + "operationId": "get-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Cancel template version dry-run by job ID", + "operationId": "cancel-template-version-dry-run-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version dry-run logs by job ID", + "operationId": "get-template-version-dry-run-logs-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/templateversions/{templateversion}/dry-run/{jobID}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template version dry-run resources by job ID", + "operationId": "get-template-version-dry-run-resources-by-job-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Job ID", + "name": "jobID", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/templateversions/{templateversion}/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get git auth by template version", + "operationId": "get-git-auth-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionGitAuth" + } + } + } + } + } + }, + "/templateversions/{templateversion}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get logs by template version", + "operationId": "get-logs-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/templateversions/{templateversion}/parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get parameters by template version", + "operationId": "get-parameters-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/parameter.ComputedValue" + } + } + } + } + } + }, + "/templateversions/{templateversion}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get resources by template version", + "operationId": "get-resources-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/templateversions/{templateversion}/rich-parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get rich parameters by template version", + "operationId": "get-rich-parameters-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionParameter" + } + } + } + } + } + }, + "/templateversions/{templateversion}/schema": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get schema by template version", + "operationId": "get-schema-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ParameterSchema" + } + } + } + } + } + }, + "/templateversions/{templateversion}/variables": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Templates"], + "summary": "Get template variables by template version", + "operationId": "get-template-variables-by-template-version", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Template version ID", + "name": "templateversion", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionVariable" + } + } + } + } + } + }, + "/updatecheck": { + "get": { + "produces": ["application/json"], + "tags": ["General"], + "summary": "Update check", + "operationId": "update-check", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.UpdateCheckResponse" + } + } + } + } + }, + "/users": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get users", + "operationId": "get-users", + "parameters": [ + { + "type": "string", + "description": "Search query", + "name": "q", + "in": "query" + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GetUsersResponse" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create new user", + "operationId": "create-new-user", + "parameters": [ + { + "description": "Create user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/authmethods": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get authentication methods", + "operationId": "get-authentication-methods", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.AuthMethods" + } + } + } + } + }, + "/users/first": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Check initial user created", + "operationId": "check-initial-user-created", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create initial user", + "operationId": "create-initial-user", + "parameters": [ + { + "description": "First user request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.CreateFirstUserResponse" + } + } + } + } + }, + "/users/login": { + "post": { + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Authorization"], + "summary": "Log in user", + "operationId": "log-in-user", + "parameters": [ + { + "description": "Login request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.LoginWithPasswordResponse" + } + } + } + } + }, + "/users/logout": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Log out user", + "operationId": "log-out-user", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/users/oauth2/github/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Users"], + "summary": "OAuth 2.0 GitHub Callback", + "operationId": "oauth-20-github-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/oidc/callback": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Users"], + "summary": "OpenID Connect Callback", + "operationId": "openid-connect-callback", + "responses": { + "307": { + "description": "Temporary Redirect" + } + } + } + }, + "/users/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Members"], + "summary": "Get site member roles", + "operationId": "get-site-member-roles", + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AssignableRoles" + } + } + } + } + } + }, + "/users/{user}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user by name", + "operationId": "get-user-by-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Delete user", + "operationId": "delete-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user Git SSH key", + "operationId": "get-user-git-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Regenerate user SSH key", + "operationId": "regenerate-user-ssh-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.GitSSHKey" + } + } + } + } + }, + "/users/{user}/keys": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create new session key", + "operationId": "create-new-session-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, + "/users/{user}/keys/tokens": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user tokens", + "operationId": "get-user-tokens", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Create token API key", + "operationId": "create-token-api-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Create token request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateTokenRequest" + } + } + ], + "responses": { + "201": { + "description": "Created", + "schema": { + "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" + } + } + } + } + }, + "/users/{user}/keys/tokens/tokenconfig": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["General"], + "summary": "Get token config", + "operationId": "get-token-config", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.TokenConfig" + } + } + } + } + }, + "/users/{user}/keys/tokens/{keyname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get API key by token name", + "operationId": "get-api-key-by-token-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "string", + "description": "Key Name", + "name": "keyname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + } + }, + "/users/{user}/keys/{keyid}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get API key by ID", + "operationId": "get-api-key-by-id", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.APIKey" + } + } + } + }, + "delete": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Users"], + "summary": "Delete API key", + "operationId": "delete-api-key", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "Key ID", + "name": "keyid", + "in": "path", + "required": true + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/users/{user}/organizations": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get organizations by user", + "operationId": "get-organizations-by-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + } + }, + "/users/{user}/organizations/{organizationname}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get organization by user and organization name", + "operationId": "get-organization-by-user-and-organization-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Organization name", + "name": "organizationname", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Organization" + } + } + } + } + }, + "/users/{user}/password": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Users"], + "summary": "Update user password", + "operationId": "update-user-password", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update password request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserPasswordRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/users/{user}/profile": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Update user profile", + "operationId": "update-user-profile", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Updated profile", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateUserProfileRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/roles": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Get user roles", + "operationId": "get-user-roles", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Assign role to user", + "operationId": "assign-role-to-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "description": "Update roles request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateRoles" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/status/activate": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Activate user account", + "operationId": "activate-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/status/suspend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Users"], + "summary": "Suspend user account", + "operationId": "suspend-user-account", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.User" + } + } + } + } + }, + "/users/{user}/workspace/{workspacename}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace metadata by user and workspace name", + "operationId": "get-workspace-metadata-by-user-and-workspace-name", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Return data instead of HTTP 404 if the workspace is deleted", + "name": "include_deleted", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + } + }, + "/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace build by user, workspace name, and build number", + "operationId": "get-workspace-build-by-user-workspace-name-and-build-number", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + }, + { + "type": "string", + "description": "Workspace name", + "name": "workspacename", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "number", + "description": "Build number", + "name": "buildnumber", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspace-quota/{user}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Enterprise"], + "summary": "Get workspace quota by user", + "operationId": "get-workspace-quota-by-user", + "parameters": [ + { + "type": "string", + "description": "User ID, name, or me", + "name": "user", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceQuota" + } + } + } + } + }, + "/workspaceagents/aws-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Authenticate agent on AWS instance", + "operationId": "authenticate-agent-on-aws-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.AWSInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/azure-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Authenticate agent on Azure instance", + "operationId": "authenticate-agent-on-azure-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.AzureInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/google-instance-identity": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Authenticate agent on Google Cloud instance", + "operationId": "authenticate-agent-on-google-cloud-instance", + "parameters": [ + { + "description": "Instance identity token", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.GoogleInstanceIdentityToken" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.AuthenticateResponse" + } + } + } + } + }, + "/workspaceagents/me/app-health": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace agent application health", + "operationId": "submit-workspace-agent-application-health", + "parameters": [ + { + "description": "Application health request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostAppHealthsRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/workspaceagents/me/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "description": "It accepts a WebSocket connection to an agent that listens to\nincoming connections and publishes node updates.", + "tags": ["Agents"], + "summary": "Coordinate workspace agent via Tailnet", + "operationId": "coordinate-workspace-agent-via-tailnet", + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/me/gitauth": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent Git auth", + "operationId": "get-workspace-agent-git-auth", + "parameters": [ + { + "type": "string", + "format": "uri", + "description": "Git URL", + "name": "url", + "in": "query", + "required": true + }, + { + "type": "boolean", + "description": "Wait for a new token to be issued", + "name": "listen", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.GitAuthResponse" + } + } + } + } + }, + "/workspaceagents/me/gitsshkey": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent Git SSH key", + "operationId": "get-workspace-agent-git-ssh-key", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.GitSSHKey" + } + } + } + } + }, + "/workspaceagents/me/metadata": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get authorized workspace agent metadata", + "operationId": "get-authorized-workspace-agent-metadata", + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.Metadata" + } + } + } + } + }, + "/workspaceagents/me/report-lifecycle": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace agent lifecycle state", + "operationId": "submit-workspace-agent-lifecycle-state", + "parameters": [ + { + "description": "Workspace agent lifecycle request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostLifecycleRequest" + } + } + ], + "responses": { + "204": { + "description": "Success" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceagents/me/report-stats": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace agent stats", + "operationId": "submit-workspace-agent-stats", + "parameters": [ + { + "description": "Stats request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.Stats" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/agentsdk.StatsResponse" + } + } + } + } + }, + "/workspaceagents/me/startup": { + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Submit workspace agent startup", + "operationId": "submit-workspace-agent-startup", + "parameters": [ + { + "description": "Startup request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/agentsdk.PostStartupRequest" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + }, + "x-apidocgen": { + "skip": true + } + } + }, + "/workspaceagents/{workspaceagent}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get workspace agent by ID", + "operationId": "get-workspace-agent-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/connection": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get connection info for workspace agent", + "operationId": "get-connection-info-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentConnectionInfo" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/coordinate": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Coordinate workspace agent", + "operationId": "coordinate-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspaceagents/{workspaceagent}/listening-ports": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Agents"], + "summary": "Get listening ports for workspace agent", + "operationId": "get-listening-ports-for-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPortsResponse" + } + } + } + } + }, + "/workspaceagents/{workspaceagent}/pty": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "tags": ["Agents"], + "summary": "Open PTY to workspace agent", + "operationId": "open-pty-to-workspace-agent", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace agent ID", + "name": "workspaceagent", + "in": "path", + "required": true + } + ], + "responses": { + "101": { + "description": "Switching Protocols" + } + } + } + }, + "/workspacebuilds/{workspacebuild}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace build", + "operationId": "get-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/cancel": { + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Cancel workspace build", + "operationId": "cancel-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/logs": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace build logs", + "operationId": "get-workspace-build-logs", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + }, + { + "type": "integer", + "description": "Before Unix timestamp", + "name": "before", + "in": "query" + }, + { + "type": "integer", + "description": "After Unix timestamp", + "name": "after", + "in": "query" + }, + { + "type": "boolean", + "description": "Follow log stream", + "name": "follow", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ProvisionerJobLog" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/parameters": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get build parameters for workspace build", + "operationId": "get-build-parameters-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/resources": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace resources for workspace build", + "operationId": "get-workspace-resources-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + } + } + } + } + }, + "/workspacebuilds/{workspacebuild}/state": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get provisioner state for workspace build", + "operationId": "get-provisioner-state-for-workspace-build", + "parameters": [ + { + "type": "string", + "description": "Workspace build ID", + "name": "workspacebuild", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspaces": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "List workspaces", + "operationId": "list-workspaces", + "parameters": [ + { + "type": "string", + "description": "Filter by owner username", + "name": "owner", + "in": "query" + }, + { + "type": "string", + "description": "Filter by template name", + "name": "template", + "in": "query" + }, + { + "type": "string", + "description": "Filter with partial-match by workspace name", + "name": "name", + "in": "query" + }, + { + "enum": [ + "pending", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleted", + "deleting" + ], + "type": "string", + "description": "Filter by workspace status", + "name": "status", + "in": "query" + }, + { + "enum": ["connected", "connecting", "disconnected", "timeout"], + "type": "string", + "description": "Filter by agent status", + "name": "has_agent", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspacesResponse" + } + } + } + } + }, + "/workspaces/{workspace}": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Get workspace metadata by ID", + "operationId": "get-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "boolean", + "description": "Return data instead of HTTP 404 if the workspace is deleted", + "name": "include_deleted", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + }, + "patch": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace metadata by ID", + "operationId": "update-workspace-metadata-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Metadata update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/autostart": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace autostart schedule by ID", + "operationId": "update-workspace-autostart-schedule-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Schedule update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/builds": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Get workspace builds by workspace ID", + "operationId": "get-workspace-builds-by-workspace-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "type": "string", + "format": "uuid", + "description": "After ID", + "name": "after_id", + "in": "query" + }, + { + "type": "integer", + "description": "Page limit", + "name": "limit", + "in": "query" + }, + { + "type": "integer", + "description": "Page offset", + "name": "offset", + "in": "query" + }, + { + "type": "string", + "format": "date-time", + "description": "Since timestamp", + "name": "since", + "in": "query" + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "post": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Builds"], + "summary": "Create workspace build", + "operationId": "create-workspace-build", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Create workspace build request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.CreateWorkspaceBuildRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" + } + } + } + } + }, + "/workspaces/{workspace}/extend": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "produces": ["application/json"], + "tags": ["Workspaces"], + "summary": "Extend workspace deadline by ID", + "operationId": "extend-workspace-deadline-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Extend deadline update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.PutExtendWorkspaceRequest" + } + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + }, + "/workspaces/{workspace}/ttl": { + "put": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "consumes": ["application/json"], + "tags": ["Workspaces"], + "summary": "Update workspace TTL by ID", + "operationId": "update-workspace-ttl-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + }, + { + "description": "Workspace TTL update request", + "name": "request", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/codersdk.UpdateWorkspaceTTLRequest" + } + } + ], + "responses": { + "204": { + "description": "No Content" + } + } + } + }, + "/workspaces/{workspace}/watch": { + "get": { + "security": [ + { + "CoderSessionToken": [] + } + ], + "produces": ["text/event-stream"], + "tags": ["Workspaces"], + "summary": "Watch workspace by ID", + "operationId": "watch-workspace-by-id", + "parameters": [ + { + "type": "string", + "format": "uuid", + "description": "Workspace ID", + "name": "workspace", + "in": "path", + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "schema": { + "$ref": "#/definitions/codersdk.Response" + } + } + } + } + } + }, + "definitions": { + "agentsdk.AWSInstanceIdentityToken": { + "type": "object", + "required": ["document", "signature"], + "properties": { + "document": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, + "agentsdk.AuthenticateResponse": { + "type": "object", + "properties": { + "session_token": { + "type": "string" + } + } + }, + "agentsdk.AzureInstanceIdentityToken": { + "type": "object", + "required": ["encoding", "signature"], + "properties": { + "encoding": { + "type": "string" + }, + "signature": { + "type": "string" + } + } + }, + "agentsdk.GitAuthResponse": { + "type": "object", + "properties": { + "password": { + "type": "string" + }, + "url": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "agentsdk.GitSSHKey": { + "type": "object", + "properties": { + "private_key": { + "type": "string" + }, + "public_key": { + "type": "string" + } + } + }, + "agentsdk.GoogleInstanceIdentityToken": { + "type": "object", + "required": ["json_web_token"], + "properties": { + "json_web_token": { + "type": "string" + } + } + }, + "agentsdk.Metadata": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } + }, + "derpmap": { + "$ref": "#/definitions/tailcfg.DERPMap" + }, + "directory": { + "type": "string" + }, + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "git_auth_configs": { + "description": "GitAuthConfigs stores the number of Git configurations\nthe Coder deployment has. If this number is \u003e0, we\nset up special configuration in the workspace.", + "type": "integer" + }, + "motd_file": { + "type": "string" + }, + "shutdown_script": { + "type": "string" + }, + "shutdown_script_timeout": { + "type": "integer" + }, + "startup_script": { + "type": "string" + }, + "startup_script_timeout": { + "type": "integer" + }, + "vscode_port_proxy_uri": { + "type": "string" + } + } + }, + "agentsdk.PostAppHealthsRequest": { + "type": "object", + "properties": { + "healths": { + "description": "Healths is a map of the workspace app name and the health of the app.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.WorkspaceAppHealth" + } + } + } + }, + "agentsdk.PostLifecycleRequest": { + "type": "object", + "properties": { + "state": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" + } + } + }, + "agentsdk.PostStartupRequest": { + "type": "object", + "properties": { + "expanded_directory": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "agentsdk.Stats": { + "type": "object", + "properties": { + "connection_count": { + "description": "ConnectionCount is the number of connections received by an agent.", + "type": "integer" + }, + "connection_median_latency_ms": { + "description": "ConnectionMedianLatencyMS is the median latency of all connections in milliseconds.", + "type": "number" + }, + "connections_by_proto": { + "description": "ConnectionsByProto is a count of connections by protocol.", + "type": "object", + "additionalProperties": { + "type": "integer" + } + }, + "rx_bytes": { + "description": "RxBytes is the number of received bytes.", + "type": "integer" + }, + "rx_packets": { + "description": "RxPackets is the number of received packets.", + "type": "integer" + }, + "session_count_jetbrains": { + "description": "SessionCountJetBrains is the number of connections received by an agent\nthat are from our JetBrains extension.", + "type": "integer" + }, + "session_count_reconnecting_pty": { + "description": "SessionCountReconnectingPTY is the number of connections received by an agent\nthat are from the reconnecting web terminal.", + "type": "integer" + }, + "session_count_ssh": { + "description": "SessionCountSSH is the number of connections received by an agent\nthat are normal, non-tagged SSH sessions.", + "type": "integer" + }, + "session_count_vscode": { + "description": "SessionCountVSCode is the number of connections received by an agent\nthat are from our VS Code extension.", + "type": "integer" + }, + "tx_bytes": { + "description": "TxBytes is the number of transmitted bytes.", + "type": "integer" + }, + "tx_packets": { + "description": "TxPackets is the number of transmitted bytes.", + "type": "integer" + } + } + }, + "agentsdk.StatsResponse": { + "type": "object", + "properties": { + "report_interval": { + "description": "ReportInterval is the duration after which the agent should send stats\nagain.", + "type": "integer" + } + } + }, + "clibase.Annotations": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "clibase.Group": { + "type": "object", + "properties": { + "children": { + "type": "array", + "items": { + "$ref": "#/definitions/clibase.Group" + } + }, + "description": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parent": { + "$ref": "#/definitions/clibase.Group" + } + } + }, + "clibase.HostPort": { + "type": "object", + "properties": { + "host": { + "type": "string" + }, + "port": { + "type": "string" + } + } + }, + "clibase.Option": { + "type": "object", + "properties": { + "annotations": { + "description": "Annotations enable extensions to clibase higher up in the stack. It's useful for\nhelp formatting and documentation generation.", + "allOf": [ + { + "$ref": "#/definitions/clibase.Annotations" + } + ] + }, + "default": { + "description": "Default is parsed into Value if set.", + "type": "string" + }, + "description": { + "type": "string" + }, + "env": { + "description": "Env is the environment variable used to configure this option. If unset,\nenvironment configuring is disabled.", + "type": "string" + }, + "flag": { + "description": "Flag is the long name of the flag used to configure this option. If unset,\nflag configuring is disabled.", + "type": "string" + }, + "flag_shorthand": { + "description": "FlagShorthand is the one-character shorthand for the flag. If unset, no\nshorthand is used.", + "type": "string" + }, + "group": { + "description": "Group is a group hierarchy that helps organize this option in help, configs\nand other documentation.", + "allOf": [ + { + "$ref": "#/definitions/clibase.Group" + } + ] + }, + "hidden": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "use_instead": { + "description": "UseInstead is a list of options that should be used instead of this one.\nThe field is used to generate a deprecation warning.", + "type": "array", + "items": { + "$ref": "#/definitions/clibase.Option" + } + }, + "value": { + "description": "Value includes the types listed in values.go." + }, + "yaml": { + "description": "YAML is the YAML key used to configure this option. If unset, YAML\nconfiguring is disabled.", + "type": "string" + } + } + }, + "clibase.Struct-array_codersdk_GitAuthConfig": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.GitAuthConfig" + } + } + } + }, + "clibase.Struct-array_codersdk_LinkConfig": { + "type": "object", + "properties": { + "value": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.LinkConfig" + } + } + } + }, + "clibase.URL": { + "type": "object", + "properties": { + "forceQuery": { + "description": "append a query ('?') even if RawQuery is empty", + "type": "boolean" + }, + "fragment": { + "description": "fragment for references, without '#'", + "type": "string" + }, + "host": { + "description": "host or host:port", + "type": "string" + }, + "omitHost": { + "description": "do not emit empty host (authority)", + "type": "boolean" + }, + "opaque": { + "description": "encoded opaque data", + "type": "string" + }, + "path": { + "description": "path (relative paths may omit leading slash)", + "type": "string" + }, + "rawFragment": { + "description": "encoded fragment hint (see EscapedFragment method)", + "type": "string" + }, + "rawPath": { + "description": "encoded path hint (see EscapedPath method)", + "type": "string" + }, + "rawQuery": { + "description": "encoded query values, without '?'", + "type": "string" + }, + "scheme": { + "type": "string" + }, + "user": { + "description": "username and password information", + "allOf": [ + { + "$ref": "#/definitions/url.Userinfo" + } + ] + } + } + }, + "coderd.SCIMUser": { + "type": "object", + "properties": { + "active": { + "type": "boolean" + }, + "emails": { + "type": "array", + "items": { + "type": "object", + "properties": { + "display": { + "type": "string" + }, + "primary": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "value": { + "type": "string", + "format": "email" + } + } + } + }, + "groups": { + "type": "array", + "items": {} + }, + "id": { + "type": "string" + }, + "meta": { + "type": "object", + "properties": { + "resourceType": { + "type": "string" + } + } + }, + "name": { + "type": "object", + "properties": { + "familyName": { + "type": "string" + }, + "givenName": { + "type": "string" + } + } + }, + "schemas": { + "type": "array", + "items": { + "type": "string" + } + }, + "userName": { + "type": "string" + } + } + }, + "coderd.cspViolation": { + "type": "object", + "properties": { + "csp-report": { + "type": "object", + "additionalProperties": true + } + } + }, + "codersdk.APIKey": { + "type": "object", + "required": [ + "created_at", + "expires_at", + "id", + "last_used", + "lifetime_seconds", + "login_type", + "scope", + "token_name", + "updated_at", + "user_id" + ], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "expires_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string" + }, + "last_used": { + "type": "string", + "format": "date-time" + }, + "lifetime_seconds": { + "type": "integer" + }, + "login_type": { + "enum": ["password", "github", "oidc", "token"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.LoginType" + } + ] + }, + "scope": { + "enum": ["all", "application_connect"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.APIKeyScope" + } + ] + }, + "token_name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.APIKeyScope": { + "type": "string", + "enum": ["all", "application_connect"], + "x-enum-varnames": ["APIKeyScopeAll", "APIKeyScopeApplicationConnect"] + }, + "codersdk.AddLicenseRequest": { + "type": "object", + "required": ["license"], + "properties": { + "license": { + "type": "string" + } + } + }, + "codersdk.AppHostResponse": { + "type": "object", + "properties": { + "host": { + "description": "Host is the externally accessible URL for the Coder instance.", + "type": "string" + } + } + }, + "codersdk.AppearanceConfig": { + "type": "object", + "properties": { + "logo_url": { + "type": "string" + }, + "service_banner": { + "$ref": "#/definitions/codersdk.ServiceBannerConfig" + }, + "support_links": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.LinkConfig" + } + } + } + }, + "codersdk.AssignableRoles": { + "type": "object", + "properties": { + "assignable": { + "type": "boolean" + }, + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.AuditAction": { + "type": "string", + "enum": ["create", "write", "delete", "start", "stop", "login", "logout"], + "x-enum-varnames": [ + "AuditActionCreate", + "AuditActionWrite", + "AuditActionDelete", + "AuditActionStart", + "AuditActionStop", + "AuditActionLogin", + "AuditActionLogout" + ] + }, + "codersdk.AuditDiff": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuditDiffField" + } + }, + "codersdk.AuditDiffField": { + "type": "object", + "properties": { + "new": {}, + "old": {}, + "secret": { + "type": "boolean" + } + } + }, + "codersdk.AuditLog": { + "type": "object", + "properties": { + "action": { + "$ref": "#/definitions/codersdk.AuditAction" + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "description": { + "type": "string" + }, + "diff": { + "$ref": "#/definitions/codersdk.AuditDiff" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "ip": { + "type": "string" + }, + "is_deleted": { + "type": "boolean" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "request_id": { + "type": "string", + "format": "uuid" + }, + "resource_icon": { + "type": "string" + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "resource_link": { + "type": "string" + }, + "resource_target": { + "description": "ResourceTarget is the name of the resource.", + "type": "string" + }, + "resource_type": { + "$ref": "#/definitions/codersdk.ResourceType" + }, + "status_code": { + "type": "integer" + }, + "time": { + "type": "string", + "format": "date-time" + }, + "user": { + "$ref": "#/definitions/codersdk.User" + }, + "user_agent": { + "type": "string" + } + } + }, + "codersdk.AuditLogResponse": { + "type": "object", + "properties": { + "audit_logs": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.AuditLog" + } + }, + "count": { + "type": "integer" + } + } + }, + "codersdk.AuthMethod": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + } + } + }, + "codersdk.AuthMethods": { + "type": "object", + "properties": { + "github": { + "$ref": "#/definitions/codersdk.AuthMethod" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCAuthMethod" + }, + "password": { + "$ref": "#/definitions/codersdk.AuthMethod" + } + } + }, + "codersdk.AuthorizationCheck": { + "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", + "type": "object", + "properties": { + "action": { + "type": "string", + "enum": ["create", "read", "update", "delete"] + }, + "object": { + "description": "Object can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product.\nWhen defining an object, use the most specific language when possible to\nproduce the smallest set. Meaning to set as many fields on 'Object' as\nyou can. Example, if you want to check if you can update all workspaces\nowned by 'me', try to also add an 'OrganizationID' to the settings.\nOmitting the 'OrganizationID' could produce the incorrect value, as\nworkspaces have both `user` and `organization` owners.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.AuthorizationObject" + } + ] + } + } + }, + "codersdk.AuthorizationObject": { + "description": "AuthorizationObject can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.", + "type": "object", + "properties": { + "organization_id": { + "description": "OrganizationID (optional) adds the set constraint to all resources owned by a given organization.", + "type": "string" + }, + "owner_id": { + "description": "OwnerID (optional) adds the set constraint to all resources owned by a given user.", + "type": "string" + }, + "resource_id": { + "description": "ResourceID (optional) reduces the set to a singular resource. This assigns\na resource ID to the resource type, eg: a single workspace.\nThe rbac library will not fetch the resource from the database, so if you\nare using this option, you should also set the owner ID and organization ID\nif possible. Be as specific as possible using all the fields relevant.", + "type": "string" + }, + "resource_type": { + "description": "ResourceType is the name of the resource.\n`./coderd/rbac/object.go` has the list of valid resource types.", + "type": "string" + } + } + }, + "codersdk.AuthorizationRequest": { + "type": "object", + "properties": { + "checks": { + "description": "Checks is a map keyed with an arbitrary string to a permission check.\nThe key can be any string that is helpful to the caller, and allows\nmultiple permission checks to be run in a single request.\nThe key ensures that each permission check has the same key in the\nresponse.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.AuthorizationCheck" + } + } + } + }, + "codersdk.AuthorizationResponse": { + "type": "object", + "additionalProperties": { + "type": "boolean" + } + }, + "codersdk.BuildInfoResponse": { + "type": "object", + "properties": { + "external_url": { + "description": "ExternalURL references the current Coder version.\nFor production builds, this will link directly to a release. For development builds, this will link to a commit.", + "type": "string" + }, + "version": { + "description": "Version returns the semantic version of the build.", + "type": "string" + } + } + }, + "codersdk.BuildReason": { + "type": "string", + "enum": ["initiator", "autostart", "autostop"], + "x-enum-varnames": [ + "BuildReasonInitiator", + "BuildReasonAutostart", + "BuildReasonAutostop" + ] + }, + "codersdk.CreateFirstUserRequest": { + "type": "object", + "required": ["email", "password", "username"], + "properties": { + "email": { + "type": "string" + }, + "password": { + "type": "string" + }, + "trial": { + "type": "boolean" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateFirstUserResponse": { + "type": "object", + "properties": { + "organization_id": { + "type": "string", + "format": "uuid" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.CreateGroupRequest": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "name": { + "type": "string" + }, + "quota_allowance": { + "type": "integer" + } + } + }, + "codersdk.CreateOrganizationRequest": { + "type": "object", + "required": ["name"], + "properties": { + "name": { + "type": "string" + } + } + }, + "codersdk.CreateParameterRequest": { + "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", + "type": "object", + "required": [ + "destination_scheme", + "name", + "source_scheme", + "source_value" + ], + "properties": { + "copy_from_parameter": { + "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", + "type": "string", + "format": "uuid" + }, + "destination_scheme": { + "enum": ["none", "environment_variable", "provisioner_variable"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterDestinationScheme" + } + ] + }, + "name": { + "type": "string" + }, + "source_scheme": { + "enum": ["none", "data"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterSourceScheme" + } + ] + }, + "source_value": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateRequest": { + "type": "object", + "required": ["name", "template_version_id"], + "properties": { + "allow_user_cancel_workspace_jobs": { + "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", + "type": "boolean" + }, + "default_ttl_ms": { + "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", + "type": "integer" + }, + "description": { + "description": "Description is a description of what the template contains. It must be\nless than 128 bytes.", + "type": "string" + }, + "display_name": { + "description": "DisplayName is the displayed name of the template.", + "type": "string" + }, + "icon": { + "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", + "type": "string" + }, + "max_ttl_ms": { + "description": "MaxTTLMillis allows optionally specifying the max lifetime for\nworkspaces created from this template.", + "type": "integer" + }, + "name": { + "description": "Name is the name of the template.", + "type": "string" + }, + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "template_version_id": { + "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.CreateTemplateVersionDryRunRequest": { + "type": "object", + "properties": { + "parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "user_variable_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.VariableValue" + } + }, + "workspace_name": { + "type": "string" + } + } + }, + "codersdk.CreateTemplateVersionRequest": { + "type": "object", + "required": ["provisioner", "storage_method"], + "properties": { + "example_id": { + "type": "string" + }, + "file_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "parameter_values": { + "description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "provisioner": { + "type": "string", + "enum": ["terraform", "echo"] + }, + "storage_method": { + "enum": ["file"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerStorageMethod" + } + ] + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "template_id": { + "description": "TemplateID optionally associates a version with a template.", + "type": "string", + "format": "uuid" + }, + "user_variable_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.VariableValue" + } + } + } + }, + "codersdk.CreateTestAuditLogRequest": { + "type": "object", + "properties": { + "action": { + "enum": ["create", "write", "delete", "start", "stop"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.AuditAction" + } + ] + }, + "additional_fields": { + "type": "array", + "items": { + "type": "integer" + } + }, + "build_reason": { + "enum": ["autostart", "autostop", "initiator"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.BuildReason" + } + ] + }, + "resource_id": { + "type": "string", + "format": "uuid" + }, + "resource_type": { + "enum": [ + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "auditable_group" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ResourceType" + } + ] + }, + "time": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.CreateTokenRequest": { + "type": "object", + "properties": { + "lifetime": { + "type": "integer" + }, + "scope": { + "enum": ["all", "application_connect"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.APIKeyScope" + } + ] + }, + "token_name": { + "type": "string" + } + } + }, + "codersdk.CreateUserRequest": { + "type": "object", + "required": ["email", "organization_id", "password", "username"], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "password": { + "type": "string" + }, + "username": { + "type": "string" + } + } + }, + "codersdk.CreateWorkspaceBuildRequest": { + "type": "object", + "required": ["transition"], + "properties": { + "dry_run": { + "type": "boolean" + }, + "orphan": { + "description": "Orphan may be set for the Destroy transition.", + "type": "boolean" + }, + "parameter_values": { + "description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "state": { + "type": "array", + "items": { + "type": "integer" + } + }, + "template_version_id": { + "type": "string", + "format": "uuid" + }, + "transition": { + "enum": ["create", "start", "stop", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + } + } + }, + "codersdk.CreateWorkspaceRequest": { + "type": "object", + "required": ["name", "template_id"], + "properties": { + "autostart_schedule": { + "type": "string" + }, + "name": { + "type": "string" + }, + "parameter_values": { + "description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.CreateParameterRequest" + } + }, + "rich_parameter_values": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" + } + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "ttl_ms": { + "type": "integer" + } + } + }, + "codersdk.DAUEntry": { + "type": "object", + "properties": { + "amount": { + "type": "integer" + }, + "date": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.DERP": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DERPConfig" + }, + "server": { + "$ref": "#/definitions/codersdk.DERPServerConfig" + } + } + }, + "codersdk.DERPConfig": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "url": { + "type": "string" + } + } + }, + "codersdk.DERPRegion": { + "type": "object", + "properties": { + "latency_ms": { + "type": "number" + }, + "preferred": { + "type": "boolean" + } + } + }, + "codersdk.DERPServerConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "region_code": { + "type": "string" + }, + "region_id": { + "type": "integer" + }, + "region_name": { + "type": "string" + }, + "relay_url": { + "$ref": "#/definitions/clibase.URL" + }, + "stun_addresses": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.DangerousConfig": { + "type": "object", + "properties": { + "allow_path_app_sharing": { + "type": "boolean" + }, + "allow_path_app_site_owner_access": { + "type": "boolean" + } + } + }, + "codersdk.DeploymentConfig": { + "type": "object", + "properties": { + "config": { + "$ref": "#/definitions/codersdk.DeploymentValues" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/clibase.Option" + } + } + } + }, + "codersdk.DeploymentDAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + } + } + }, + "codersdk.DeploymentStats": { + "type": "object", + "properties": { + "aggregated_from": { + "description": "AggregatedFrom is the time in which stats are aggregated from.\nThis might be back in time a specific duration or interval.", + "type": "string", + "format": "date-time" + }, + "collected_at": { + "description": "CollectedAt is the time in which stats are collected at.", + "type": "string", + "format": "date-time" + }, + "next_update_at": { + "description": "NextUpdateAt is the time when the next batch of stats will\nbe updated.", + "type": "string", + "format": "date-time" + }, + "session_count": { + "$ref": "#/definitions/codersdk.SessionCountDeploymentStats" + }, + "workspaces": { + "$ref": "#/definitions/codersdk.WorkspaceDeploymentStats" + } + } + }, + "codersdk.DeploymentValues": { + "type": "object", + "properties": { + "access_url": { + "$ref": "#/definitions/clibase.URL" + }, + "address": { + "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", + "allOf": [ + { + "$ref": "#/definitions/clibase.HostPort" + } + ] + }, + "agent_fallback_troubleshooting_url": { + "$ref": "#/definitions/clibase.URL" + }, + "agent_stat_refresh_interval": { + "type": "integer" + }, + "audit_logging": { + "type": "boolean" + }, + "autobuild_poll_interval": { + "type": "integer" + }, + "browser_only": { + "type": "boolean" + }, + "cache_directory": { + "type": "string" + }, + "config": { + "type": "string" + }, + "config_ssh": { + "$ref": "#/definitions/codersdk.SSHConfig" + }, + "dangerous": { + "$ref": "#/definitions/codersdk.DangerousConfig" + }, + "derp": { + "$ref": "#/definitions/codersdk.DERP" + }, + "disable_password_auth": { + "type": "boolean" + }, + "disable_path_apps": { + "type": "boolean" + }, + "disable_session_expiry_refresh": { + "type": "boolean" + }, + "experiments": { + "type": "array", + "items": { + "type": "string" + } + }, + "git_auth": { + "$ref": "#/definitions/clibase.Struct-array_codersdk_GitAuthConfig" + }, + "http_address": { + "description": "HTTPAddress is a string because it may be set to zero to disable.", + "type": "string" + }, + "in_memory_database": { + "type": "boolean" + }, + "logging": { + "$ref": "#/definitions/codersdk.LoggingConfig" + }, + "max_session_expiry": { + "type": "integer" + }, + "max_token_lifetime": { + "type": "integer" + }, + "metrics_cache_refresh_interval": { + "type": "integer" + }, + "oauth2": { + "$ref": "#/definitions/codersdk.OAuth2Config" + }, + "oidc": { + "$ref": "#/definitions/codersdk.OIDCConfig" + }, + "pg_connection_url": { + "type": "string" + }, + "pprof": { + "$ref": "#/definitions/codersdk.PprofConfig" + }, + "prometheus": { + "$ref": "#/definitions/codersdk.PrometheusConfig" + }, + "provisioner": { + "$ref": "#/definitions/codersdk.ProvisionerConfig" + }, + "proxy_trusted_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "proxy_trusted_origins": { + "type": "array", + "items": { + "type": "string" + } + }, + "rate_limit": { + "$ref": "#/definitions/codersdk.RateLimitConfig" + }, + "redirect_to_access_url": { + "type": "boolean" + }, + "scim_api_key": { + "type": "string" + }, + "secure_auth_cookie": { + "type": "boolean" + }, + "ssh_keygen_algorithm": { + "type": "string" + }, + "strict_transport_security": { + "type": "integer" + }, + "strict_transport_security_options": { + "type": "array", + "items": { + "type": "string" + } + }, + "support": { + "$ref": "#/definitions/codersdk.SupportConfig" + }, + "swagger": { + "$ref": "#/definitions/codersdk.SwaggerConfig" + }, + "telemetry": { + "$ref": "#/definitions/codersdk.TelemetryConfig" + }, + "tls": { + "$ref": "#/definitions/codersdk.TLSConfig" + }, + "trace": { + "$ref": "#/definitions/codersdk.TraceConfig" + }, + "update_check": { + "type": "boolean" + }, + "verbose": { + "type": "boolean" + }, + "wildcard_access_url": { + "$ref": "#/definitions/clibase.URL" + }, + "write_config": { + "type": "boolean" + } + } + }, + "codersdk.Entitlement": { + "type": "string", + "enum": ["entitled", "grace_period", "not_entitled"], + "x-enum-varnames": [ + "EntitlementEntitled", + "EntitlementGracePeriod", + "EntitlementNotEntitled" + ] + }, + "codersdk.Entitlements": { + "type": "object", + "properties": { + "errors": { + "type": "array", + "items": { + "type": "string" + } + }, + "features": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.Feature" + } + }, + "has_license": { + "type": "boolean" + }, + "require_telemetry": { + "type": "boolean" + }, + "trial": { + "type": "boolean" + }, + "warnings": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.Experiment": { + "type": "string", + "enum": ["authz_querier", "template_editor"], + "x-enum-varnames": ["ExperimentAuthzQuerier", "ExperimentTemplateEditor"] + }, + "codersdk.Feature": { + "type": "object", + "properties": { + "actual": { + "type": "integer" + }, + "enabled": { + "type": "boolean" + }, + "entitlement": { + "$ref": "#/definitions/codersdk.Entitlement" + }, + "limit": { + "type": "integer" + } + } + }, + "codersdk.GenerateAPIKeyResponse": { + "type": "object", + "properties": { + "key": { + "type": "string" + } + } + }, + "codersdk.GetUsersResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "users": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + } + } + }, + "codersdk.GitAuthConfig": { + "type": "object", + "properties": { + "auth_url": { + "type": "string" }, - "license": { - "name": "AGPL-3.0", - "url": "https://github.com/coder/coder/blob/main/LICENSE" - }, - "version": "2.0" - }, - "basePath": "/api/v2", - "paths": { - "/": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "API root handler", - "operationId": "api-root-handler", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/appearance": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get appearance", - "operationId": "get-appearance", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AppearanceConfig" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Update appearance", - "operationId": "update-appearance", - "parameters": [ - { - "description": "Update appearance request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UpdateAppearanceConfig" - } - } - } - } - }, - "/applications/auth-redirect": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Applications" - ], - "summary": "Redirect to URI with encrypted API key", - "operationId": "redirect-to-uri-with-encrypted-api-key", - "parameters": [ - { - "type": "string", - "description": "Redirect destination", - "name": "redirect_uri", - "in": "query" - } - ], - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/applications/host": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Applications" - ], - "summary": "Get applications host", - "operationId": "get-applications-host", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AppHostResponse" - } - } - } - } - }, - "/audit": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Audit" - ], - "summary": "Get audit logs", - "operationId": "get-audit-logs", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "q", - "in": "query", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuditLogResponse" - } - } - } - } - }, - "/audit/testgenerate": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "Audit" - ], - "summary": "Generate fake audit log", - "operationId": "generate-fake-audit-log", - "parameters": [ - { - "description": "Audit log request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTestAuditLogRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/authcheck": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Authorization" - ], - "summary": "Check authorization", - "operationId": "check-authorization", - "parameters": [ - { - "description": "Authorization request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.AuthorizationRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuthorizationResponse" - } - } - } - } - }, - "/buildinfo": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Build info", - "operationId": "build-info", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.BuildInfoResponse" - } - } - } - } - }, - "/csp/reports": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Report CSP violations", - "operationId": "report-csp-violations", - "parameters": [ - { - "description": "Violation report", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.cspViolation" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/debug/coordinator": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "text/html" - ], - "tags": [ - "Debug" - ], - "summary": "Debug Info Wireguard Coordinator", - "operationId": "debug-info-wireguard-coordinator", - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/deployment/config": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Get deployment config", - "operationId": "get-deployment-config", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentConfig" - } - } - } - } - }, - "/deployment/ssh": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "SSH Config", - "operationId": "ssh-config", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.SSHConfigResponse" - } - } - } - } - }, - "/deployment/stats": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Get deployment stats", - "operationId": "get-deployment-stats", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentStats" - } - } - } - } - }, - "/entitlements": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get entitlements", - "operationId": "get-entitlements", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Entitlements" - } - } - } - } - }, - "/experiments": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Get experiments", - "operationId": "get-experiments", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Experiment" - } - } - } - } - } - }, - "/files": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "Swagger notice: Swagger 2.0 doesn't support file upload with a `content-type` different than `application/x-www-form-urlencoded`.", - "consumes": [ - "application/x-tar" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Files" - ], - "summary": "Upload file", - "operationId": "upload-file", - "parameters": [ - { - "type": "string", - "default": "application/x-tar", - "description": "Content-Type must be `application/x-tar`", - "name": "Content-Type", - "in": "header", - "required": true - }, - { - "type": "file", - "description": "File to be uploaded", - "name": "file", - "in": "formData", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.UploadResponse" - } - } - } - } - }, - "/files/{fileID}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Files" - ], - "summary": "Get file by ID", - "operationId": "get-file-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "File ID", - "name": "fileID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/groups": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get groups", - "operationId": "get-groups", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - } - }, - "/groups/{group}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get group by name", - "operationId": "get-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Delete group by name", - "operationId": "delete-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Update group by name", - "operationId": "update-group-by-name", - "parameters": [ - { - "type": "string", - "description": "Group name", - "name": "group", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/insights/daus": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Insights" - ], - "summary": "Get deployment DAUs", - "operationId": "get-deployment-daus", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.DeploymentDAUsResponse" - } - } - } - } - }, - "/licenses": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get licenses", - "operationId": "get-licenses", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.License" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Organizations" - ], - "summary": "Add new license", - "operationId": "add-new-license", - "parameters": [ - { - "description": "Add license request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.AddLicenseRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.License" - } - } - } - } - }, - "/licenses/{id}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Delete license", - "operationId": "delete-license", - "parameters": [ - { - "type": "string", - "format": "number", - "description": "License ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/organizations": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Organizations" - ], - "summary": "Create organization", - "operationId": "create-organization", - "parameters": [ - { - "description": "Create organization request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateOrganizationRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/organizations/{organization}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Organizations" - ], - "summary": "Get organization by ID", - "operationId": "get-organization-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/organizations/{organization}/groups": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get groups by organization", - "operationId": "get-groups-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Create group for organization", - "operationId": "create-group-for-organization", - "parameters": [ - { - "description": "Create group request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateGroupRequest" - } - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/organizations/{organization}/groups/{groupName}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get group by organization and group name", - "operationId": "get-group-by-organization-and-group-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Group name", - "name": "groupName", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Group" - } - } - } - } - }, - "/organizations/{organization}/members/roles": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Members" - ], - "summary": "Get member roles by organization", - "operationId": "get-member-roles-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AssignableRoles" - } - } - } - } - } - }, - "/organizations/{organization}/members/{user}/roles": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Members" - ], - "summary": "Assign role to organization member", - "operationId": "assign-role-to-organization-member", - "parameters": [ - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update roles request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateRoles" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.OrganizationMember" - } - } - } - } - }, - "/organizations/{organization}/members/{user}/workspaces": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Create user workspace by organization", - "operationId": "create-user-workspace-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Username, UUID, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Create workspace request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/organizations/{organization}/provisionerdaemons": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get provisioner daemons", - "operationId": "get-provisioner-daemons", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerDaemon" - } - } - } - } - } - }, - "/organizations/{organization}/provisionerdaemons/serve": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Enterprise" - ], - "summary": "Serve provisioner daemon", - "operationId": "serve-provisioner-daemon", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/organizations/{organization}/templates": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get templates by organization", - "operationId": "get-templates-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Create template by organization", - "operationId": "create-template-by-organization", - "parameters": [ - { - "description": "Request body", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateRequest" - } - }, - { - "type": "string", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/organizations/{organization}/templates/examples": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template examples by organization", - "operationId": "get-template-examples-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateExample" - } - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get templates by organization and template name", - "operationId": "get-templates-by-organization-and-template-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template version by organization, template, and name", - "operationId": "get-template-version-by-organization-template-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/organizations/{organization}/templates/{templatename}/versions/{templateversionname}/previous": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get previous template version by organization, template, and name", - "operationId": "get-previous-template-version-by-organization-template-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template name", - "name": "templatename", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/organizations/{organization}/templateversions": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Create template version by organization", - "operationId": "create-template-version-by-organization", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Organization ID", - "name": "organization", - "in": "path", - "required": true - }, - { - "description": "Create template version request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateVersionRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/parameters/{scope}/{id}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Parameters" - ], - "summary": "Get parameters", - "operationId": "get-parameters", - "parameters": [ - { - "enum": [ - "template", - "workspace", - "import_job" - ], - "type": "string", - "description": "Scope", - "name": "scope", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Parameter" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Parameters" - ], - "summary": "Create parameter", - "operationId": "create-parameter", - "parameters": [ - { - "description": "Parameter request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - { - "enum": [ - "template", - "workspace", - "import_job" - ], - "type": "string", - "description": "Scope", - "name": "scope", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.Parameter" - } - } - } - } - }, - "/parameters/{scope}/{id}/{name}": { - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Parameters" - ], - "summary": "Delete parameter", - "operationId": "delete-parameter", - "parameters": [ - { - "enum": [ - "template", - "workspace", - "import_job" - ], - "type": "string", - "description": "Scope", - "name": "scope", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "ID", - "name": "id", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Name", - "name": "name", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/replicas": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get active replicas", - "operationId": "get-active-replicas", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Replica" - } - } - } - } - } - }, - "/scim/v2/Users": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/scim+json" - ], - "tags": [ - "Enterprise" - ], - "summary": "SCIM 2.0: Get users", - "operationId": "scim-get-users", - "responses": { - "200": { - "description": "OK" - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "SCIM 2.0: Create new user", - "operationId": "scim-create-new-user", - "parameters": [ - { - "description": "New user", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - } - } - }, - "/scim/v2/Users/{id}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/scim+json" - ], - "tags": [ - "Enterprise" - ], - "summary": "SCIM 2.0: Get user by ID", - "operationId": "scim-get-user-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "id", - "in": "path", - "required": true - } - ], - "responses": { - "404": { - "description": "Not Found" - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/scim+json" - ], - "tags": [ - "Enterprise" - ], - "summary": "SCIM 2.0: Update user account", - "operationId": "scim-update-user-status", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "User ID", - "name": "id", - "in": "path", - "required": true - }, - { - "description": "Update user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/coderd.SCIMUser" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/templates/{template}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template metadata by ID", - "operationId": "get-template-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Delete template by ID", - "operationId": "delete-template-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Update template metadata by ID", - "operationId": "update-template-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Template" - } - } - } - } - }, - "/templates/{template}/acl": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get template ACLs", - "operationId": "get-template-acls", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateUser" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Update template ACL", - "operationId": "update-template-acl", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "description": "Update template request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateTemplateACL" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/daus": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template DAUs by ID", - "operationId": "get-template-daus-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateDAUsResponse" - } - } - } - } - }, - "/templates/{template}/versions": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "List template versions by template ID", - "operationId": "list-template-versions-by-template-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Update active template version by template ID", - "operationId": "update-active-template-version-by-template-id", - "parameters": [ - { - "description": "Modified template version", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateActiveTemplateVersion" - } - }, - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templates/{template}/versions/{templateversionname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template version by template ID and name", - "operationId": "get-template-version-by-template-id-and-name", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template ID", - "name": "template", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Template version name", - "name": "templateversionname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - } - }, - "/templateversions/{templateversion}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template version by ID", - "operationId": "get-template-version-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TemplateVersion" - } - } - } - } - }, - "/templateversions/{templateversion}/cancel": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Cancel template version by ID", - "operationId": "cancel-template-version-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Create template version dry-run", - "operationId": "create-template-version-dry-run", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "description": "Dry-run request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTemplateVersionDryRunRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template version dry-run by job ID", - "operationId": "get-template-version-dry-run-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}/cancel": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Cancel template version dry-run by job ID", - "operationId": "cancel-template-version-dry-run-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template version dry-run logs by job ID", - "operationId": "get-template-version-dry-run-logs-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } - } - } - } - } - }, - "/templateversions/{templateversion}/dry-run/{jobID}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template version dry-run resources by job ID", - "operationId": "get-template-version-dry-run-resources-by-job-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Job ID", - "name": "jobID", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/templateversions/{templateversion}/gitauth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get git auth by template version", - "operationId": "get-git-auth-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionGitAuth" - } - } - } - } - } - }, - "/templateversions/{templateversion}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get logs by template version", - "operationId": "get-logs-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } - } - } - } - } - }, - "/templateversions/{templateversion}/parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get parameters by template version", - "operationId": "get-parameters-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/parameter.ComputedValue" - } - } - } - } - } - }, - "/templateversions/{templateversion}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get resources by template version", - "operationId": "get-resources-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/templateversions/{templateversion}/rich-parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get rich parameters by template version", - "operationId": "get-rich-parameters-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionParameter" - } - } - } - } - } - }, - "/templateversions/{templateversion}/schema": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get schema by template version", - "operationId": "get-schema-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ParameterSchema" - } - } - } - } - } - }, - "/templateversions/{templateversion}/variables": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Templates" - ], - "summary": "Get template variables by template version", - "operationId": "get-template-variables-by-template-version", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Template version ID", - "name": "templateversion", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionVariable" - } - } - } - } - } - }, - "/updatecheck": { - "get": { - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Update check", - "operationId": "update-check", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.UpdateCheckResponse" - } - } - } - } - }, - "/users": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get users", - "operationId": "get-users", - "parameters": [ - { - "type": "string", - "description": "Search query", - "name": "q", - "in": "query" - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.GetUsersResponse" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Create new user", - "operationId": "create-new-user", - "parameters": [ - { - "description": "Create user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateUserRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/authmethods": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get authentication methods", - "operationId": "get-authentication-methods", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.AuthMethods" - } - } - } - } - }, - "/users/first": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Check initial user created", - "operationId": "check-initial-user-created", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Create initial user", - "operationId": "create-initial-user", - "parameters": [ - { - "description": "First user request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateFirstUserRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.CreateFirstUserResponse" - } - } - } - } - }, - "/users/login": { - "post": { - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Authorization" - ], - "summary": "Log in user", - "operationId": "log-in-user", - "parameters": [ - { - "description": "Login request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.LoginWithPasswordRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.LoginWithPasswordResponse" - } - } - } - } - }, - "/users/logout": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Log out user", - "operationId": "log-out-user", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/users/oauth2/github/callback": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Users" - ], - "summary": "OAuth 2.0 GitHub Callback", - "operationId": "oauth-20-github-callback", - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/users/oidc/callback": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Users" - ], - "summary": "OpenID Connect Callback", - "operationId": "openid-connect-callback", - "responses": { - "307": { - "description": "Temporary Redirect" - } - } - } - }, - "/users/roles": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Members" - ], - "summary": "Get site member roles", - "operationId": "get-site-member-roles", - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AssignableRoles" - } - } - } - } - } - }, - "/users/{user}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get user by name", - "operationId": "get-user-by-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Delete user", - "operationId": "delete-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/gitsshkey": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get user Git SSH key", - "operationId": "get-user-git-ssh-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.GitSSHKey" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Regenerate user SSH key", - "operationId": "regenerate-user-ssh-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.GitSSHKey" - } - } - } - } - }, - "/users/{user}/keys": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Create new session key", - "operationId": "create-new-session-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" - } - } - } - } - }, - "/users/{user}/keys/tokens": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get user tokens", - "operationId": "get-user-tokens", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Create token API key", - "operationId": "create-token-api-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Create token request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateTokenRequest" - } - } - ], - "responses": { - "201": { - "description": "Created", - "schema": { - "$ref": "#/definitions/codersdk.GenerateAPIKeyResponse" - } - } - } - } - }, - "/users/{user}/keys/tokens/tokenconfig": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "General" - ], - "summary": "Get token config", - "operationId": "get-token-config", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.TokenConfig" - } - } - } - } - }, - "/users/{user}/keys/tokens/{keyname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get API key by token name", - "operationId": "get-api-key-by-token-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "string", - "description": "Key Name", - "name": "keyname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - } - }, - "/users/{user}/keys/{keyid}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get API key by ID", - "operationId": "get-api-key-by-id", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Key ID", - "name": "keyid", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.APIKey" - } - } - } - }, - "delete": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Users" - ], - "summary": "Delete API key", - "operationId": "delete-api-key", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "Key ID", - "name": "keyid", - "in": "path", - "required": true - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/users/{user}/organizations": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get organizations by user", - "operationId": "get-organizations-by-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - } - }, - "/users/{user}/organizations/{organizationname}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get organization by user and organization name", - "operationId": "get-organization-by-user-and-organization-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Organization name", - "name": "organizationname", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Organization" - } - } - } - } - }, - "/users/{user}/password": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Update user password", - "operationId": "update-user-password", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update password request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserPasswordRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/users/{user}/profile": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Update user profile", - "operationId": "update-user-profile", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Updated profile", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateUserProfileRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/roles": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Get user roles", - "operationId": "get-user-roles", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Assign role to user", - "operationId": "assign-role-to-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "description": "Update roles request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateRoles" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/status/activate": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Activate user account", - "operationId": "activate-user-account", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/status/suspend": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Users" - ], - "summary": "Suspend user account", - "operationId": "suspend-user-account", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.User" - } - } - } - } - }, - "/users/{user}/workspace/{workspacename}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Get workspace metadata by user and workspace name", - "operationId": "get-workspace-metadata-by-user-and-workspace-name", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace name", - "name": "workspacename", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Return data instead of HTTP 404 if the workspace is deleted", - "name": "include_deleted", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - } - }, - "/users/{user}/workspace/{workspacename}/builds/{buildnumber}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get workspace build by user, workspace name, and build number", - "operationId": "get-workspace-build-by-user-workspace-name-and-build-number", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - }, - { - "type": "string", - "description": "Workspace name", - "name": "workspacename", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "number", - "description": "Build number", - "name": "buildnumber", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspace-quota/{user}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Enterprise" - ], - "summary": "Get workspace quota by user", - "operationId": "get-workspace-quota-by-user", - "parameters": [ - { - "type": "string", - "description": "User ID, name, or me", - "name": "user", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceQuota" - } - } - } - } - }, - "/workspaceagents/aws-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Authenticate agent on AWS instance", - "operationId": "authenticate-agent-on-aws-instance", - "parameters": [ - { - "description": "Instance identity token", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.AWSInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/azure-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Authenticate agent on Azure instance", - "operationId": "authenticate-agent-on-azure-instance", - "parameters": [ - { - "description": "Instance identity token", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.AzureInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/google-instance-identity": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Authenticate agent on Google Cloud instance", - "operationId": "authenticate-agent-on-google-cloud-instance", - "parameters": [ - { - "description": "Instance identity token", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.GoogleInstanceIdentityToken" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.AuthenticateResponse" - } - } - } - } - }, - "/workspaceagents/me/app-health": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Submit workspace agent application health", - "operationId": "submit-workspace-agent-application-health", - "parameters": [ - { - "description": "Application health request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostAppHealthsRequest" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - } - } - }, - "/workspaceagents/me/coordinate": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "description": "It accepts a WebSocket connection to an agent that listens to\nincoming connections and publishes node updates.", - "tags": [ - "Agents" - ], - "summary": "Coordinate workspace agent via Tailnet", - "operationId": "coordinate-workspace-agent-via-tailnet", - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspaceagents/me/gitauth": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Get workspace agent Git auth", - "operationId": "get-workspace-agent-git-auth", - "parameters": [ - { - "type": "string", - "format": "uri", - "description": "Git URL", - "name": "url", - "in": "query", - "required": true - }, - { - "type": "boolean", - "description": "Wait for a new token to be issued", - "name": "listen", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.GitAuthResponse" - } - } - } - } - }, - "/workspaceagents/me/gitsshkey": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Get workspace agent Git SSH key", - "operationId": "get-workspace-agent-git-ssh-key", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.GitSSHKey" - } - } - } - } - }, - "/workspaceagents/me/metadata": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Get authorized workspace agent metadata", - "operationId": "get-authorized-workspace-agent-metadata", - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.Metadata" - } - } - } - } - }, - "/workspaceagents/me/report-lifecycle": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Submit workspace agent lifecycle state", - "operationId": "submit-workspace-agent-lifecycle-state", - "parameters": [ - { - "description": "Workspace agent lifecycle request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostLifecycleRequest" - } - } - ], - "responses": { - "204": { - "description": "Success" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceagents/me/report-stats": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Submit workspace agent stats", - "operationId": "submit-workspace-agent-stats", - "parameters": [ - { - "description": "Stats request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.Stats" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/agentsdk.StatsResponse" - } - } - } - } - }, - "/workspaceagents/me/startup": { - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Submit workspace agent startup", - "operationId": "submit-workspace-agent-startup", - "parameters": [ - { - "description": "Startup request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/agentsdk.PostStartupRequest" - } - } - ], - "responses": { - "200": { - "description": "OK" - } - }, - "x-apidocgen": { - "skip": true - } - } - }, - "/workspaceagents/{workspaceagent}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Get workspace agent by ID", - "operationId": "get-workspace-agent-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgent" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/connection": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Get connection info for workspace agent", - "operationId": "get-connection-info-for-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentConnectionInfo" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/coordinate": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Agents" - ], - "summary": "Coordinate workspace agent", - "operationId": "coordinate-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspaceagents/{workspaceagent}/listening-ports": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Agents" - ], - "summary": "Get listening ports for workspace agent", - "operationId": "get-listening-ports-for-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPortsResponse" - } - } - } - } - }, - "/workspaceagents/{workspaceagent}/pty": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "tags": [ - "Agents" - ], - "summary": "Open PTY to workspace agent", - "operationId": "open-pty-to-workspace-agent", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace agent ID", - "name": "workspaceagent", - "in": "path", - "required": true - } - ], - "responses": { - "101": { - "description": "Switching Protocols" - } - } - } - }, - "/workspacebuilds/{workspacebuild}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get workspace build", - "operationId": "get-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/cancel": { - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Cancel workspace build", - "operationId": "cancel-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/logs": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get workspace build logs", - "operationId": "get-workspace-build-logs", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - }, - { - "type": "integer", - "description": "Before Unix timestamp", - "name": "before", - "in": "query" - }, - { - "type": "integer", - "description": "After Unix timestamp", - "name": "after", - "in": "query" - }, - { - "type": "boolean", - "description": "Follow log stream", - "name": "follow", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ProvisionerJobLog" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/parameters": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get build parameters for workspace build", - "operationId": "get-build-parameters-for-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/resources": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get workspace resources for workspace build", - "operationId": "get-workspace-resources-for-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - } - } - } - } - }, - "/workspacebuilds/{workspacebuild}/state": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get provisioner state for workspace build", - "operationId": "get-provisioner-state-for-workspace-build", - "parameters": [ - { - "type": "string", - "description": "Workspace build ID", - "name": "workspacebuild", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspaces": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "List workspaces", - "operationId": "list-workspaces", - "parameters": [ - { - "type": "string", - "description": "Filter by owner username", - "name": "owner", - "in": "query" - }, - { - "type": "string", - "description": "Filter by template name", - "name": "template", - "in": "query" - }, - { - "type": "string", - "description": "Filter with partial-match by workspace name", - "name": "name", - "in": "query" - }, - { - "enum": [ - "pending", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleted", - "deleting" - ], - "type": "string", - "description": "Filter by workspace status", - "name": "status", - "in": "query" - }, - { - "enum": [ - "connected", - "connecting", - "disconnected", - "timeout" - ], - "type": "string", - "description": "Filter by agent status", - "name": "has_agent", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspacesResponse" - } - } - } - } - }, - "/workspaces/{workspace}": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Get workspace metadata by ID", - "operationId": "get-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "type": "boolean", - "description": "Return data instead of HTTP 404 if the workspace is deleted", - "name": "include_deleted", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } - }, - "patch": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Update workspace metadata by ID", - "operationId": "update-workspace-metadata-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Metadata update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/autostart": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Update workspace autostart schedule by ID", - "operationId": "update-workspace-autostart-schedule-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Schedule update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceAutostartRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/builds": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Get workspace builds by workspace ID", - "operationId": "get-workspace-builds-by-workspace-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "type": "string", - "format": "uuid", - "description": "After ID", - "name": "after_id", - "in": "query" - }, - { - "type": "integer", - "description": "Page limit", - "name": "limit", - "in": "query" - }, - { - "type": "integer", - "description": "Page offset", - "name": "offset", - "in": "query" - }, - { - "type": "string", - "format": "date-time", - "description": "Since timestamp", - "name": "since", - "in": "query" - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "post": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Builds" - ], - "summary": "Create workspace build", - "operationId": "create-workspace-build", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Create workspace build request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.CreateWorkspaceBuildRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - } - } - } - } - }, - "/workspaces/{workspace}/extend": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "produces": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Extend workspace deadline by ID", - "operationId": "extend-workspace-deadline-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Extend deadline update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.PutExtendWorkspaceRequest" - } - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - }, - "/workspaces/{workspace}/ttl": { - "put": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "consumes": [ - "application/json" - ], - "tags": [ - "Workspaces" - ], - "summary": "Update workspace TTL by ID", - "operationId": "update-workspace-ttl-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - }, - { - "description": "Workspace TTL update request", - "name": "request", - "in": "body", - "required": true, - "schema": { - "$ref": "#/definitions/codersdk.UpdateWorkspaceTTLRequest" - } - } - ], - "responses": { - "204": { - "description": "No Content" - } - } - } - }, - "/workspaces/{workspace}/watch": { - "get": { - "security": [ - { - "CoderSessionToken": [] - } - ], - "produces": [ - "text/event-stream" - ], - "tags": [ - "Workspaces" - ], - "summary": "Watch workspace by ID", - "operationId": "watch-workspace-by-id", - "parameters": [ - { - "type": "string", - "format": "uuid", - "description": "Workspace ID", - "name": "workspace", - "in": "path", - "required": true - } - ], - "responses": { - "200": { - "description": "OK", - "schema": { - "$ref": "#/definitions/codersdk.Response" - } - } - } - } - } - }, - "definitions": { - "agentsdk.AWSInstanceIdentityToken": { - "type": "object", - "required": [ - "document", - "signature" - ], - "properties": { - "document": { - "type": "string" - }, - "signature": { - "type": "string" - } - } + "client_id": { + "type": "string" }, - "agentsdk.AuthenticateResponse": { - "type": "object", - "properties": { - "session_token": { - "type": "string" - } - } + "id": { + "type": "string" }, - "agentsdk.AzureInstanceIdentityToken": { - "type": "object", - "required": [ - "encoding", - "signature" - ], - "properties": { - "encoding": { - "type": "string" - }, - "signature": { - "type": "string" - } - } + "no_refresh": { + "type": "boolean" }, - "agentsdk.GitAuthResponse": { - "type": "object", - "properties": { - "password": { - "type": "string" - }, - "url": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "agentsdk.GitSSHKey": { - "type": "object", - "properties": { - "private_key": { - "type": "string" - }, - "public_key": { - "type": "string" - } - } + "regex": { + "type": "string" }, - "agentsdk.GoogleInstanceIdentityToken": { - "type": "object", - "required": [ - "json_web_token" - ], - "properties": { - "json_web_token": { - "type": "string" - } - } + "scopes": { + "type": "array", + "items": { + "type": "string" + } }, - "agentsdk.Metadata": { - "type": "object", - "properties": { - "apps": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceApp" - } - }, - "derpmap": { - "$ref": "#/definitions/tailcfg.DERPMap" - }, - "directory": { - "type": "string" - }, - "environment_variables": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "git_auth_configs": { - "description": "GitAuthConfigs stores the number of Git configurations\nthe Coder deployment has. If this number is \u003e0, we\nset up special configuration in the workspace.", - "type": "integer" - }, - "motd_file": { - "type": "string" - }, - "shutdown_script": { - "type": "string" - }, - "shutdown_script_timeout": { - "type": "integer" - }, - "startup_script": { - "type": "string" - }, - "startup_script_timeout": { - "type": "integer" - }, - "vscode_port_proxy_uri": { - "type": "string" - } - } - }, - "agentsdk.PostAppHealthsRequest": { - "type": "object", - "properties": { - "healths": { - "description": "Healths is a map of the workspace app name and the health of the app.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.WorkspaceAppHealth" - } - } + "token_url": { + "type": "string" + }, + "type": { + "type": "string" + }, + "validate_url": { + "type": "string" + } + } + }, + "codersdk.GitProvider": { + "type": "string", + "enum": ["azure-devops", "github", "gitlab", "bitbucket"], + "x-enum-varnames": [ + "GitProviderAzureDevops", + "GitProviderGitHub", + "GitProviderGitLab", + "GitProviderBitBucket" + ] + }, + "codersdk.GitSSHKey": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "public_key": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.Group": { + "type": "object", + "properties": { + "avatar_url": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "members": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.User" + } + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "quota_allowance": { + "type": "integer" + } + } + }, + "codersdk.Healthcheck": { + "type": "object", + "properties": { + "interval": { + "description": "Interval specifies the seconds between each health check.", + "type": "integer" + }, + "threshold": { + "description": "Threshold specifies the number of consecutive failed health checks before returning \"unhealthy\".", + "type": "integer" + }, + "url": { + "description": "URL specifies the endpoint to check for the app health.", + "type": "string" + } + } + }, + "codersdk.JobErrorCode": { + "type": "string", + "enum": ["MISSING_TEMPLATE_PARAMETER", "REQUIRED_TEMPLATE_VARIABLES"], + "x-enum-varnames": [ + "MissingTemplateParameter", + "RequiredTemplateVariables" + ] + }, + "codersdk.License": { + "type": "object", + "properties": { + "claims": { + "description": "Claims are the JWT claims asserted by the license. Here we use\na generic string map to ensure that all data from the server is\nparsed verbatim, not just the fields this version of Coder\nunderstands.", + "type": "object", + "additionalProperties": true + }, + "id": { + "type": "integer" + }, + "uploaded_at": { + "type": "string", + "format": "date-time" + }, + "uuid": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.LinkConfig": { + "type": "object", + "properties": { + "icon": { + "type": "string" + }, + "name": { + "type": "string" + }, + "target": { + "type": "string" + } + } + }, + "codersdk.LogLevel": { + "type": "string", + "enum": ["trace", "debug", "info", "warn", "error"], + "x-enum-varnames": [ + "LogLevelTrace", + "LogLevelDebug", + "LogLevelInfo", + "LogLevelWarn", + "LogLevelError" + ] + }, + "codersdk.LogSource": { + "type": "string", + "enum": ["provisioner_daemon", "provisioner"], + "x-enum-varnames": ["LogSourceProvisionerDaemon", "LogSourceProvisioner"] + }, + "codersdk.LoggingConfig": { + "type": "object", + "properties": { + "human": { + "type": "string" + }, + "json": { + "type": "string" + }, + "stackdriver": { + "type": "string" + } + } + }, + "codersdk.LoginType": { + "type": "string", + "enum": ["password", "github", "oidc", "token"], + "x-enum-varnames": [ + "LoginTypePassword", + "LoginTypeGithub", + "LoginTypeOIDC", + "LoginTypeToken" + ] + }, + "codersdk.LoginWithPasswordRequest": { + "type": "object", + "required": ["email", "password"], + "properties": { + "email": { + "type": "string", + "format": "email" + }, + "password": { + "type": "string" + } + } + }, + "codersdk.LoginWithPasswordResponse": { + "type": "object", + "required": ["session_token"], + "properties": { + "session_token": { + "type": "string" + } + } + }, + "codersdk.OAuth2Config": { + "type": "object", + "properties": { + "github": { + "$ref": "#/definitions/codersdk.OAuth2GithubConfig" + } + } + }, + "codersdk.OAuth2GithubConfig": { + "type": "object", + "properties": { + "allow_everyone": { + "type": "boolean" + }, + "allow_signups": { + "type": "boolean" + }, + "allowed_orgs": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_teams": { + "type": "array", + "items": { + "type": "string" + } + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "enterprise_base_url": { + "type": "string" + } + } + }, + "codersdk.OIDCAuthMethod": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "iconUrl": { + "type": "string" + }, + "signInText": { + "type": "string" + } + } + }, + "codersdk.OIDCConfig": { + "type": "object", + "properties": { + "allow_signups": { + "type": "boolean" + }, + "client_id": { + "type": "string" + }, + "client_secret": { + "type": "string" + }, + "email_domain": { + "type": "array", + "items": { + "type": "string" + } + }, + "groups_field": { + "type": "string" + }, + "icon_url": { + "$ref": "#/definitions/clibase.URL" + }, + "ignore_email_verified": { + "type": "boolean" + }, + "issuer_url": { + "type": "string" + }, + "scopes": { + "type": "array", + "items": { + "type": "string" + } + }, + "sign_in_text": { + "type": "string" + }, + "username_field": { + "type": "string" + } + } + }, + "codersdk.Organization": { + "type": "object", + "required": ["created_at", "id", "name", "updated_at"], + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.OrganizationMember": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "user_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.Parameter": { + "description": "Parameter represents a set value for the scope.", + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "destination_scheme": { + "enum": ["none", "environment_variable", "provisioner_variable"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterDestinationScheme" + } + ] + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "scope": { + "enum": ["template", "workspace", "import_job"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterScope" + } + ] + }, + "scope_id": { + "type": "string", + "format": "uuid" + }, + "source_scheme": { + "enum": ["none", "data"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterSourceScheme" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.ParameterDestinationScheme": { + "type": "string", + "enum": ["none", "environment_variable", "provisioner_variable"], + "x-enum-varnames": [ + "ParameterDestinationSchemeNone", + "ParameterDestinationSchemeEnvironmentVariable", + "ParameterDestinationSchemeProvisionerVariable" + ] + }, + "codersdk.ParameterSchema": { + "type": "object", + "properties": { + "allow_override_destination": { + "type": "boolean" + }, + "allow_override_source": { + "type": "boolean" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "default_destination_scheme": { + "enum": ["none", "environment_variable", "provisioner_variable"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterDestinationScheme" } + ] }, - "agentsdk.PostLifecycleRequest": { - "type": "object", - "properties": { - "state": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" - } + "default_refresh": { + "type": "string" + }, + "default_source_scheme": { + "enum": ["none", "data"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ParameterSourceScheme" } + ] }, - "agentsdk.PostStartupRequest": { - "type": "object", - "properties": { - "expanded_directory": { - "type": "string" - }, - "version": { - "type": "string" - } + "default_source_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "redisplay_value": { + "type": "boolean" + }, + "validation_condition": { + "type": "string" + }, + "validation_contains": { + "description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.", + "type": "array", + "items": { + "type": "string" + } + }, + "validation_error": { + "type": "string" + }, + "validation_type_system": { + "type": "string" + }, + "validation_value_type": { + "type": "string" + } + } + }, + "codersdk.ParameterScope": { + "type": "string", + "enum": ["template", "workspace", "import_job"], + "x-enum-varnames": [ + "ParameterTemplate", + "ParameterWorkspace", + "ParameterImportJob" + ] + }, + "codersdk.ParameterSourceScheme": { + "type": "string", + "enum": ["none", "data"], + "x-enum-varnames": [ + "ParameterSourceSchemeNone", + "ParameterSourceSchemeData" + ] + }, + "codersdk.PprofConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/clibase.HostPort" + }, + "enable": { + "type": "boolean" + } + } + }, + "codersdk.PrometheusConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/clibase.HostPort" + }, + "enable": { + "type": "boolean" + } + } + }, + "codersdk.ProvisionerConfig": { + "type": "object", + "properties": { + "daemon_poll_interval": { + "type": "integer" + }, + "daemon_poll_jitter": { + "type": "integer" + }, + "daemons": { + "type": "integer" + }, + "force_cancel_interval": { + "type": "integer" + } + } + }, + "codersdk.ProvisionerDaemon": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "name": { + "type": "string" + }, + "provisioners": { + "type": "array", + "items": { + "type": "string" + } + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "updated_at": { + "format": "date-time", + "allOf": [ + { + "$ref": "#/definitions/sql.NullTime" + } + ] + } + } + }, + "codersdk.ProvisionerJob": { + "type": "object", + "properties": { + "canceled_at": { + "type": "string", + "format": "date-time" + }, + "completed_at": { + "type": "string", + "format": "date-time" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "error": { + "type": "string" + }, + "error_code": { + "enum": ["MISSING_TEMPLATE_PARAMETER", "REQUIRED_TEMPLATE_VARIABLES"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.JobErrorCode" + } + ] + }, + "file_id": { + "type": "string", + "format": "uuid" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "started_at": { + "type": "string", + "format": "date-time" + }, + "status": { + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ProvisionerJobStatus" + } + ] + }, + "tags": { + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "worker_id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.ProvisionerJobLog": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "integer" + }, + "log_level": { + "enum": ["trace", "debug", "info", "warn", "error"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.LogLevel" } + ] }, - "agentsdk.Stats": { - "type": "object", - "properties": { - "connection_count": { - "description": "ConnectionCount is the number of connections received by an agent.", - "type": "integer" - }, - "connection_median_latency_ms": { - "description": "ConnectionMedianLatencyMS is the median latency of all connections in milliseconds.", - "type": "number" - }, - "connections_by_proto": { - "description": "ConnectionsByProto is a count of connections by protocol.", - "type": "object", - "additionalProperties": { - "type": "integer" - } - }, - "rx_bytes": { - "description": "RxBytes is the number of received bytes.", - "type": "integer" - }, - "rx_packets": { - "description": "RxPackets is the number of received packets.", - "type": "integer" - }, - "session_count_jetbrains": { - "description": "SessionCountJetBrains is the number of connections received by an agent\nthat are from our JetBrains extension.", - "type": "integer" - }, - "session_count_reconnecting_pty": { - "description": "SessionCountReconnectingPTY is the number of connections received by an agent\nthat are from the reconnecting web terminal.", - "type": "integer" - }, - "session_count_ssh": { - "description": "SessionCountSSH is the number of connections received by an agent\nthat are normal, non-tagged SSH sessions.", - "type": "integer" - }, - "session_count_vscode": { - "description": "SessionCountVSCode is the number of connections received by an agent\nthat are from our VS Code extension.", - "type": "integer" - }, - "tx_bytes": { - "description": "TxBytes is the number of transmitted bytes.", - "type": "integer" - }, - "tx_packets": { - "description": "TxPackets is the number of transmitted bytes.", - "type": "integer" - } - } - }, - "agentsdk.StatsResponse": { - "type": "object", - "properties": { - "report_interval": { - "description": "ReportInterval is the duration after which the agent should send stats\nagain.", - "type": "integer" - } + "log_source": { + "$ref": "#/definitions/codersdk.LogSource" + }, + "output": { + "type": "string" + }, + "stage": { + "type": "string" + } + } + }, + "codersdk.ProvisionerJobStatus": { + "type": "string", + "enum": [ + "pending", + "running", + "succeeded", + "canceling", + "canceled", + "failed" + ], + "x-enum-varnames": [ + "ProvisionerJobPending", + "ProvisionerJobRunning", + "ProvisionerJobSucceeded", + "ProvisionerJobCanceling", + "ProvisionerJobCanceled", + "ProvisionerJobFailed" + ] + }, + "codersdk.ProvisionerStorageMethod": { + "type": "string", + "enum": ["file"], + "x-enum-varnames": ["ProvisionerStorageMethodFile"] + }, + "codersdk.PutExtendWorkspaceRequest": { + "type": "object", + "required": ["deadline"], + "properties": { + "deadline": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.RateLimitConfig": { + "type": "object", + "properties": { + "api": { + "type": "integer" + }, + "disable_all": { + "type": "boolean" + } + } + }, + "codersdk.Replica": { + "type": "object", + "properties": { + "created_at": { + "description": "CreatedAt is the timestamp when the replica was first seen.", + "type": "string", + "format": "date-time" + }, + "database_latency": { + "description": "DatabaseLatency is the latency in microseconds to the database.", + "type": "integer" + }, + "error": { + "description": "Error is the replica error.", + "type": "string" + }, + "hostname": { + "description": "Hostname is the hostname of the replica.", + "type": "string" + }, + "id": { + "description": "ID is the unique identifier for the replica.", + "type": "string", + "format": "uuid" + }, + "region_id": { + "description": "RegionID is the region of the replica.", + "type": "integer" + }, + "relay_address": { + "description": "RelayAddress is the accessible address to relay DERP connections.", + "type": "string" + } + } + }, + "codersdk.ResourceType": { + "type": "string", + "enum": [ + "template", + "template_version", + "user", + "workspace", + "workspace_build", + "git_ssh_key", + "api_key", + "group", + "license" + ], + "x-enum-varnames": [ + "ResourceTypeTemplate", + "ResourceTypeTemplateVersion", + "ResourceTypeUser", + "ResourceTypeWorkspace", + "ResourceTypeWorkspaceBuild", + "ResourceTypeGitSSHKey", + "ResourceTypeAPIKey", + "ResourceTypeGroup", + "ResourceTypeLicense" + ] + }, + "codersdk.Response": { + "type": "object", + "properties": { + "detail": { + "description": "Detail is a debug message that provides further insight into why the\naction failed. This information can be technical and a regular golang\nerr.Error() text.\n- \"database: too many open connections\"\n- \"stat: too many open files\"", + "type": "string" + }, + "message": { + "description": "Message is an actionable message that depicts actions the request took.\nThese messages should be fully formed sentences with proper punctuation.\nExamples:\n- \"A user has been created.\"\n- \"Failed to create a user.\"", + "type": "string" + }, + "validations": { + "description": "Validations are form field-specific friendly error messages. They will be\nshown on a form field in the UI. These can also be used to add additional\ncontext if there is a set of errors in the primary 'Message'.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.ValidationError" + } + } + } + }, + "codersdk.Role": { + "type": "object", + "properties": { + "display_name": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, + "codersdk.SSHConfig": { + "type": "object", + "properties": { + "deploymentName": { + "description": "DeploymentName is the config-ssh Hostname prefix", + "type": "string" + }, + "sshconfigOptions": { + "description": "SSHConfigOptions are additional options to add to the ssh config file.\nThis will override defaults.", + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.SSHConfigResponse": { + "type": "object", + "properties": { + "hostname_prefix": { + "type": "string" + }, + "ssh_config_options": { + "type": "object", + "additionalProperties": { + "type": "string" + } + } + } + }, + "codersdk.ServiceBannerConfig": { + "type": "object", + "properties": { + "background_color": { + "type": "string" + }, + "enabled": { + "type": "boolean" + }, + "message": { + "type": "string" + } + } + }, + "codersdk.SessionCountDeploymentStats": { + "type": "object", + "properties": { + "jetbrains": { + "type": "integer" + }, + "reconnecting_pty": { + "type": "integer" + }, + "ssh": { + "type": "integer" + }, + "vscode": { + "type": "integer" + } + } + }, + "codersdk.SupportConfig": { + "type": "object", + "properties": { + "links": { + "$ref": "#/definitions/clibase.Struct-array_codersdk_LinkConfig" + } + } + }, + "codersdk.SwaggerConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + } + } + }, + "codersdk.TLSConfig": { + "type": "object", + "properties": { + "address": { + "$ref": "#/definitions/clibase.HostPort" + }, + "cert_file": { + "type": "array", + "items": { + "type": "string" + } + }, + "client_auth": { + "type": "string" + }, + "client_ca_file": { + "type": "string" + }, + "client_cert_file": { + "type": "string" + }, + "client_key_file": { + "type": "string" + }, + "enable": { + "type": "boolean" + }, + "key_file": { + "type": "array", + "items": { + "type": "string" + } + }, + "min_version": { + "type": "string" + }, + "redirect_http": { + "type": "boolean" + } + } + }, + "codersdk.TelemetryConfig": { + "type": "object", + "properties": { + "enable": { + "type": "boolean" + }, + "trace": { + "type": "boolean" + }, + "url": { + "$ref": "#/definitions/clibase.URL" + } + } + }, + "codersdk.Template": { + "type": "object", + "properties": { + "active_user_count": { + "description": "ActiveUserCount is set to -1 when loading.", + "type": "integer" + }, + "active_version_id": { + "type": "string", + "format": "uuid" + }, + "allow_user_cancel_workspace_jobs": { + "type": "boolean" + }, + "build_time_stats": { + "$ref": "#/definitions/codersdk.TemplateBuildTimeStats" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by_id": { + "type": "string", + "format": "uuid" + }, + "created_by_name": { + "type": "string" + }, + "default_ttl_ms": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "display_name": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "max_ttl_ms": { + "description": "MaxTTLMillis is an enterprise feature. It's value is only used if your\nlicense is entitled to use the advanced template scheduling feature.", + "type": "integer" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "provisioner": { + "type": "string", + "enum": ["terraform"] + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.TemplateBuildTimeStats": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TransitionStats" + } + }, + "codersdk.TemplateDAUsResponse": { + "type": "object", + "properties": { + "entries": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.DAUEntry" + } + } + } + }, + "codersdk.TemplateExample": { + "type": "object", + "properties": { + "description": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "markdown": { + "type": "string" + }, + "name": { + "type": "string" + }, + "tags": { + "type": "array", + "items": { + "type": "string" + } + }, + "url": { + "type": "string" + } + } + }, + "codersdk.TemplateRole": { + "type": "string", + "enum": ["admin", "use", ""], + "x-enum-varnames": [ + "TemplateRoleAdmin", + "TemplateRoleUse", + "TemplateRoleDeleted" + ] + }, + "codersdk.TemplateUser": { + "type": "object", + "required": ["created_at", "email", "id", "username"], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "organization_ids": { + "type": "array", + "items": { + "type": "string", + "format": "uuid" + } + }, + "role": { + "enum": ["admin", "use"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.TemplateRole" } + ] }, - "clibase.Annotations": { - "type": "object", - "additionalProperties": { - "type": "string" + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } + }, + "status": { + "enum": ["active", "suspended"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" } + ] + }, + "username": { + "type": "string" + } + } + }, + "codersdk.TemplateVersion": { + "type": "object", + "properties": { + "created_at": { + "type": "string", + "format": "date-time" + }, + "created_by": { + "$ref": "#/definitions/codersdk.User" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "name": { + "type": "string" + }, + "organization_id": { + "type": "string", + "format": "uuid" + }, + "readme": { + "type": "string" + }, + "template_id": { + "type": "string", + "format": "uuid" + }, + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.TemplateVersionGitAuth": { + "type": "object", + "properties": { + "authenticate_url": { + "type": "string" + }, + "authenticated": { + "type": "boolean" + }, + "id": { + "type": "string" + }, + "type": { + "$ref": "#/definitions/codersdk.GitProvider" + } + } + }, + "codersdk.TemplateVersionParameter": { + "type": "object", + "properties": { + "default_value": { + "type": "string" + }, + "description": { + "type": "string" + }, + "description_plaintext": { + "type": "string" + }, + "icon": { + "type": "string" + }, + "legacy_variable_name": { + "type": "string" + }, + "mutable": { + "type": "boolean" + }, + "name": { + "type": "string" + }, + "options": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" + } + }, + "required": { + "type": "boolean" + }, + "type": { + "type": "string", + "enum": ["string", "number", "bool", "list(string)"] + }, + "validation_error": { + "type": "string" }, - "clibase.Group": { - "type": "object", - "properties": { - "children": { - "type": "array", - "items": { - "$ref": "#/definitions/clibase.Group" - } - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "parent": { - "$ref": "#/definitions/clibase.Group" - } - } - }, - "clibase.HostPort": { - "type": "object", - "properties": { - "host": { - "type": "string" - }, - "port": { - "type": "string" - } - } + "validation_max": { + "type": "integer" }, - "clibase.Option": { - "type": "object", - "properties": { - "annotations": { - "description": "Annotations enable extensions to clibase higher up in the stack. It's useful for\nhelp formatting and documentation generation.", - "allOf": [ - { - "$ref": "#/definitions/clibase.Annotations" - } - ] - }, - "default": { - "description": "Default is parsed into Value if set.", - "type": "string" - }, - "description": { - "type": "string" - }, - "env": { - "description": "Env is the environment variable used to configure this option. If unset,\nenvironment configuring is disabled.", - "type": "string" - }, - "flag": { - "description": "Flag is the long name of the flag used to configure this option. If unset,\nflag configuring is disabled.", - "type": "string" - }, - "flag_shorthand": { - "description": "FlagShorthand is the one-character shorthand for the flag. If unset, no\nshorthand is used.", - "type": "string" - }, - "group": { - "description": "Group is a group hierarchy that helps organize this option in help, configs\nand other documentation.", - "allOf": [ - { - "$ref": "#/definitions/clibase.Group" - } - ] - }, - "hidden": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "use_instead": { - "description": "UseInstead is a list of options that should be used instead of this one.\nThe field is used to generate a deprecation warning.", - "type": "array", - "items": { - "$ref": "#/definitions/clibase.Option" - } - }, - "value": { - "description": "Value includes the types listed in values.go." - }, - "yaml": { - "description": "YAML is the YAML key used to configure this option. If unset, YAML\nconfiguring is disabled.", - "type": "string" - } - } - }, - "clibase.Struct-array_codersdk_GitAuthConfig": { - "type": "object", - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.GitAuthConfig" - } - } - } + "validation_min": { + "type": "integer" }, - "clibase.Struct-array_codersdk_LinkConfig": { - "type": "object", - "properties": { - "value": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.LinkConfig" - } - } + "validation_monotonic": { + "enum": ["increasing", "decreasing"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.ValidationMonotonicOrder" } + ] }, - "clibase.URL": { - "type": "object", - "properties": { - "forceQuery": { - "description": "append a query ('?') even if RawQuery is empty", - "type": "boolean" - }, - "fragment": { - "description": "fragment for references, without '#'", - "type": "string" - }, - "host": { - "description": "host or host:port", - "type": "string" - }, - "omitHost": { - "description": "do not emit empty host (authority)", - "type": "boolean" - }, - "opaque": { - "description": "encoded opaque data", - "type": "string" - }, - "path": { - "description": "path (relative paths may omit leading slash)", - "type": "string" - }, - "rawFragment": { - "description": "encoded fragment hint (see EscapedFragment method)", - "type": "string" - }, - "rawPath": { - "description": "encoded path hint (see EscapedPath method)", - "type": "string" - }, - "rawQuery": { - "description": "encoded query values, without '?'", - "type": "string" - }, - "scheme": { - "type": "string" - }, - "user": { - "description": "username and password information", - "allOf": [ - { - "$ref": "#/definitions/url.Userinfo" - } - ] - } - } - }, - "coderd.SCIMUser": { - "type": "object", - "properties": { - "active": { - "type": "boolean" - }, - "emails": { - "type": "array", - "items": { - "type": "object", - "properties": { - "display": { - "type": "string" - }, - "primary": { - "type": "boolean" - }, - "type": { - "type": "string" - }, - "value": { - "type": "string", - "format": "email" - } - } - } - }, - "groups": { - "type": "array", - "items": {} - }, - "id": { - "type": "string" - }, - "meta": { - "type": "object", - "properties": { - "resourceType": { - "type": "string" - } - } - }, - "name": { - "type": "object", - "properties": { - "familyName": { - "type": "string" - }, - "givenName": { - "type": "string" - } - } - }, - "schemas": { - "type": "array", - "items": { - "type": "string" - } - }, - "userName": { - "type": "string" - } - } - }, - "coderd.cspViolation": { - "type": "object", - "properties": { - "csp-report": { - "type": "object", - "additionalProperties": true - } - } + "validation_regex": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionParameterOption": { + "type": "object", + "properties": { + "description": { + "type": "string" }, - "codersdk.APIKey": { - "type": "object", - "required": [ - "created_at", - "expires_at", - "id", - "last_used", - "lifetime_seconds", - "login_type", - "scope", - "token_name", - "updated_at", - "user_id" - ], - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "expires_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string" - }, - "last_used": { - "type": "string", - "format": "date-time" - }, - "lifetime_seconds": { - "type": "integer" - }, - "login_type": { - "enum": [ - "password", - "github", - "oidc", - "token" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.LoginType" - } - ] - }, - "scope": { - "enum": [ - "all", - "application_connect" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.APIKeyScope" - } - ] - }, - "token_name": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.APIKeyScope": { - "type": "string", - "enum": [ - "all", - "application_connect" - ], - "x-enum-varnames": [ - "APIKeyScopeAll", - "APIKeyScopeApplicationConnect" - ] + "icon": { + "type": "string" }, - "codersdk.AddLicenseRequest": { - "type": "object", - "required": [ - "license" - ], - "properties": { - "license": { - "type": "string" - } - } + "name": { + "type": "string" }, - "codersdk.AppHostResponse": { - "type": "object", - "properties": { - "host": { - "description": "Host is the externally accessible URL for the Coder instance.", - "type": "string" - } - } + "value": { + "type": "string" + } + } + }, + "codersdk.TemplateVersionVariable": { + "type": "object", + "properties": { + "default_value": { + "type": "string" }, - "codersdk.AppearanceConfig": { - "type": "object", - "properties": { - "logo_url": { - "type": "string" - }, - "service_banner": { - "$ref": "#/definitions/codersdk.ServiceBannerConfig" - }, - "support_links": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.LinkConfig" - } - } - } - }, - "codersdk.AssignableRoles": { - "type": "object", - "properties": { - "assignable": { - "type": "boolean" - }, - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - } - } + "description": { + "type": "string" }, - "codersdk.AuditAction": { - "type": "string", - "enum": [ - "create", - "write", - "delete", - "start", - "stop", - "login", - "logout" - ], - "x-enum-varnames": [ - "AuditActionCreate", - "AuditActionWrite", - "AuditActionDelete", - "AuditActionStart", - "AuditActionStop", - "AuditActionLogin", - "AuditActionLogout" - ] - }, - "codersdk.AuditDiff": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.AuditDiffField" - } + "name": { + "type": "string" }, - "codersdk.AuditDiffField": { - "type": "object", - "properties": { - "new": {}, - "old": {}, - "secret": { - "type": "boolean" - } - } + "required": { + "type": "boolean" }, - "codersdk.AuditLog": { - "type": "object", - "properties": { - "action": { - "$ref": "#/definitions/codersdk.AuditAction" - }, - "additional_fields": { - "type": "array", - "items": { - "type": "integer" - } - }, - "description": { - "type": "string" - }, - "diff": { - "$ref": "#/definitions/codersdk.AuditDiff" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "ip": { - "type": "string" - }, - "is_deleted": { - "type": "boolean" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "request_id": { - "type": "string", - "format": "uuid" - }, - "resource_icon": { - "type": "string" - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "resource_link": { - "type": "string" - }, - "resource_target": { - "description": "ResourceTarget is the name of the resource.", - "type": "string" - }, - "resource_type": { - "$ref": "#/definitions/codersdk.ResourceType" - }, - "status_code": { - "type": "integer" - }, - "time": { - "type": "string", - "format": "date-time" - }, - "user": { - "$ref": "#/definitions/codersdk.User" - }, - "user_agent": { - "type": "string" - } - } - }, - "codersdk.AuditLogResponse": { - "type": "object", - "properties": { - "audit_logs": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.AuditLog" - } - }, - "count": { - "type": "integer" - } - } - }, - "codersdk.AuthMethod": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - } - } + "sensitive": { + "type": "boolean" }, - "codersdk.AuthMethods": { - "type": "object", - "properties": { - "github": { - "$ref": "#/definitions/codersdk.AuthMethod" - }, - "oidc": { - "$ref": "#/definitions/codersdk.OIDCAuthMethod" - }, - "password": { - "$ref": "#/definitions/codersdk.AuthMethod" - } - } - }, - "codersdk.AuthorizationCheck": { - "description": "AuthorizationCheck is used to check if the currently authenticated user (or the specified user) can do a given action to a given set of objects.", - "type": "object", - "properties": { - "action": { - "type": "string", - "enum": [ - "create", - "read", - "update", - "delete" - ] - }, - "object": { - "description": "Object can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, and all workspaces across the entire product.\nWhen defining an object, use the most specific language when possible to\nproduce the smallest set. Meaning to set as many fields on 'Object' as\nyou can. Example, if you want to check if you can update all workspaces\nowned by 'me', try to also add an 'OrganizationID' to the settings.\nOmitting the 'OrganizationID' could produce the incorrect value, as\nworkspaces have both `user` and `organization` owners.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.AuthorizationObject" - } - ] - } - } - }, - "codersdk.AuthorizationObject": { - "description": "AuthorizationObject can represent a \"set\" of objects, such as: all workspaces in an organization, all workspaces owned by me, all workspaces across the entire product.", - "type": "object", - "properties": { - "organization_id": { - "description": "OrganizationID (optional) adds the set constraint to all resources owned by a given organization.", - "type": "string" - }, - "owner_id": { - "description": "OwnerID (optional) adds the set constraint to all resources owned by a given user.", - "type": "string" - }, - "resource_id": { - "description": "ResourceID (optional) reduces the set to a singular resource. This assigns\na resource ID to the resource type, eg: a single workspace.\nThe rbac library will not fetch the resource from the database, so if you\nare using this option, you should also set the owner ID and organization ID\nif possible. Be as specific as possible using all the fields relevant.", - "type": "string" - }, - "resource_type": { - "description": "ResourceType is the name of the resource.\n`./coderd/rbac/object.go` has the list of valid resource types.", - "type": "string" - } - } - }, - "codersdk.AuthorizationRequest": { - "type": "object", - "properties": { - "checks": { - "description": "Checks is a map keyed with an arbitrary string to a permission check.\nThe key can be any string that is helpful to the caller, and allows\nmultiple permission checks to be run in a single request.\nThe key ensures that each permission check has the same key in the\nresponse.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.AuthorizationCheck" - } - } - } + "type": { + "type": "string", + "enum": ["string", "number", "bool"] }, - "codersdk.AuthorizationResponse": { - "type": "object", - "additionalProperties": { - "type": "boolean" - } + "value": { + "type": "string" + } + } + }, + "codersdk.TokenConfig": { + "type": "object", + "properties": { + "max_token_lifetime": { + "type": "integer" + } + } + }, + "codersdk.TraceConfig": { + "type": "object", + "properties": { + "capture_logs": { + "type": "boolean" }, - "codersdk.BuildInfoResponse": { - "type": "object", - "properties": { - "external_url": { - "description": "ExternalURL references the current Coder version.\nFor production builds, this will link directly to a release. For development builds, this will link to a commit.", - "type": "string" - }, - "version": { - "description": "Version returns the semantic version of the build.", - "type": "string" - } - } + "enable": { + "type": "boolean" }, - "codersdk.BuildReason": { + "honeycomb_api_key": { + "type": "string" + } + } + }, + "codersdk.TransitionStats": { + "type": "object", + "properties": { + "p50": { + "type": "integer", + "example": 123 + }, + "p95": { + "type": "integer", + "example": 146 + } + } + }, + "codersdk.UpdateActiveTemplateVersion": { + "type": "object", + "required": ["id"], + "properties": { + "id": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.UpdateAppearanceConfig": { + "type": "object", + "properties": { + "logo_url": { + "type": "string" + }, + "service_banner": { + "$ref": "#/definitions/codersdk.ServiceBannerConfig" + } + } + }, + "codersdk.UpdateCheckResponse": { + "type": "object", + "properties": { + "current": { + "description": "Current indicates whether the server version is the same as the latest.", + "type": "boolean" + }, + "url": { + "description": "URL to download the latest release of Coder.", + "type": "string" + }, + "version": { + "description": "Version is the semantic version for the latest release of Coder.", + "type": "string" + } + } + }, + "codersdk.UpdateRoles": { + "type": "object", + "properties": { + "roles": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "codersdk.UpdateTemplateACL": { + "type": "object", + "properties": { + "group_perms": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TemplateRole" + } + }, + "user_perms": { + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.TemplateRole" + } + } + } + }, + "codersdk.UpdateUserPasswordRequest": { + "type": "object", + "required": ["password"], + "properties": { + "old_password": { + "type": "string" + }, + "password": { + "type": "string" + } + } + }, + "codersdk.UpdateUserProfileRequest": { + "type": "object", + "required": ["username"], + "properties": { + "username": { + "type": "string" + } + } + }, + "codersdk.UpdateWorkspaceAutostartRequest": { + "type": "object", + "properties": { + "schedule": { + "type": "string" + } + } + }, + "codersdk.UpdateWorkspaceRequest": { + "type": "object", + "properties": { + "name": { + "type": "string" + } + } + }, + "codersdk.UpdateWorkspaceTTLRequest": { + "type": "object", + "properties": { + "ttl_ms": { + "type": "integer" + } + } + }, + "codersdk.UploadResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string", + "format": "uuid" + } + } + }, + "codersdk.User": { + "type": "object", + "required": ["created_at", "email", "id", "username"], + "properties": { + "avatar_url": { + "type": "string", + "format": "uri" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "email": { + "type": "string", + "format": "email" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "last_seen_at": { + "type": "string", + "format": "date-time" + }, + "organization_ids": { + "type": "array", + "items": { "type": "string", - "enum": [ - "initiator", - "autostart", - "autostop" - ], - "x-enum-varnames": [ - "BuildReasonInitiator", - "BuildReasonAutostart", - "BuildReasonAutostop" - ] - }, - "codersdk.CreateFirstUserRequest": { - "type": "object", - "required": [ - "email", - "password", - "username" - ], - "properties": { - "email": { - "type": "string" - }, - "password": { - "type": "string" - }, - "trial": { - "type": "boolean" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.CreateFirstUserResponse": { - "type": "object", - "properties": { - "organization_id": { - "type": "string", - "format": "uuid" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } + "format": "uuid" + } }, - "codersdk.CreateGroupRequest": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "name": { - "type": "string" - }, - "quota_allowance": { - "type": "integer" - } - } - }, - "codersdk.CreateOrganizationRequest": { - "type": "object", - "required": [ - "name" - ], - "properties": { - "name": { - "type": "string" - } - } + "roles": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Role" + } }, - "codersdk.CreateParameterRequest": { - "description": "CreateParameterRequest is a structure used to create a new parameter value for a scope.", - "type": "object", - "required": [ - "destination_scheme", - "name", - "source_scheme", - "source_value" - ], - "properties": { - "copy_from_parameter": { - "description": "CloneID allows copying the value of another parameter.\nThe other param must be related to the same template_id for this to\nsucceed.\nNo other fields are required if using this, as all fields will be copied\nfrom the other parameter.", - "type": "string", - "format": "uuid" - }, - "destination_scheme": { - "enum": [ - "none", - "environment_variable", - "provisioner_variable" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterDestinationScheme" - } - ] - }, - "name": { - "type": "string" - }, - "source_scheme": { - "enum": [ - "none", - "data" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterSourceScheme" - } - ] - }, - "source_value": { - "type": "string" - } - } - }, - "codersdk.CreateTemplateRequest": { - "type": "object", - "required": [ - "name", - "template_version_id" - ], - "properties": { - "allow_user_cancel_workspace_jobs": { - "description": "Allow users to cancel in-progress workspace jobs.\n*bool as the default value is \"true\".", - "type": "boolean" - }, - "default_ttl_ms": { - "description": "DefaultTTLMillis allows optionally specifying the default TTL\nfor all workspaces created from this template.", - "type": "integer" - }, - "description": { - "description": "Description is a description of what the template contains. It must be\nless than 128 bytes.", - "type": "string" - }, - "display_name": { - "description": "DisplayName is the displayed name of the template.", - "type": "string" - }, - "icon": { - "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", - "type": "string" - }, - "max_ttl_ms": { - "description": "MaxTTLMillis allows optionally specifying the max lifetime for\nworkspaces created from this template.", - "type": "integer" - }, - "name": { - "description": "Name is the name of the template.", - "type": "string" - }, - "parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "template_version_id": { - "description": "VersionID is an in-progress or completed job to use as an initial version\nof the template.\n\nThis is required on creation to enable a user-flow of validating a\ntemplate works. There is no reason the data-model cannot support empty\ntemplates, but it doesn't make sense for users.", - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.CreateTemplateVersionDryRunRequest": { - "type": "object", - "properties": { - "parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "user_variable_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.VariableValue" - } - }, - "workspace_name": { - "type": "string" - } - } - }, - "codersdk.CreateTemplateVersionRequest": { - "type": "object", - "required": [ - "provisioner", - "storage_method" - ], - "properties": { - "example_id": { - "type": "string" - }, - "file_id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "parameter_values": { - "description": "ParameterValues allows for additional parameters to be provided\nduring the dry-run provision stage.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "provisioner": { - "type": "string", - "enum": [ - "terraform", - "echo" - ] - }, - "storage_method": { - "enum": [ - "file" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerStorageMethod" - } - ] - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "template_id": { - "description": "TemplateID optionally associates a version with a template.", - "type": "string", - "format": "uuid" - }, - "user_variable_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.VariableValue" - } - } - } - }, - "codersdk.CreateTestAuditLogRequest": { - "type": "object", - "properties": { - "action": { - "enum": [ - "create", - "write", - "delete", - "start", - "stop" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.AuditAction" - } - ] - }, - "additional_fields": { - "type": "array", - "items": { - "type": "integer" - } - }, - "build_reason": { - "enum": [ - "autostart", - "autostop", - "initiator" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.BuildReason" - } - ] - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "resource_type": { - "enum": [ - "template", - "template_version", - "user", - "workspace", - "workspace_build", - "git_ssh_key", - "auditable_group" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ResourceType" - } - ] - }, - "time": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.CreateTokenRequest": { - "type": "object", - "properties": { - "lifetime": { - "type": "integer" - }, - "scope": { - "enum": [ - "all", - "application_connect" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.APIKeyScope" - } - ] - }, - "token_name": { - "type": "string" - } - } - }, - "codersdk.CreateUserRequest": { - "type": "object", - "required": [ - "email", - "organization_id", - "password", - "username" - ], - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "password": { - "type": "string" - }, - "username": { - "type": "string" - } - } - }, - "codersdk.CreateWorkspaceBuildRequest": { - "type": "object", - "required": [ - "transition" - ], - "properties": { - "dry_run": { - "type": "boolean" - }, - "orphan": { - "description": "Orphan may be set for the Destroy transition.", - "type": "boolean" - }, - "parameter_values": { - "description": "ParameterValues are optional. It will write params to the 'workspace' scope.\nThis will overwrite any existing parameters with the same name.\nThis will not delete old params not included in this list.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "state": { - "type": "array", - "items": { - "type": "integer" - } - }, - "template_version_id": { - "type": "string", - "format": "uuid" - }, - "transition": { - "enum": [ - "create", - "start", - "stop", - "delete" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - } - } - }, - "codersdk.CreateWorkspaceRequest": { - "type": "object", - "required": [ - "name", - "template_id" - ], - "properties": { - "autostart_schedule": { - "type": "string" - }, - "name": { - "type": "string" - }, - "parameter_values": { - "description": "ParameterValues allows for additional parameters to be provided\nduring the initial provision.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.CreateParameterRequest" - } - }, - "rich_parameter_values": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceBuildParameter" - } - }, - "template_id": { - "type": "string", - "format": "uuid" - }, - "ttl_ms": { - "type": "integer" - } - } - }, - "codersdk.DAUEntry": { - "type": "object", - "properties": { - "amount": { - "type": "integer" - }, - "date": { - "type": "string", - "format": "date-time" - } + "status": { + "enum": ["active", "suspended"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.UserStatus" } + ] }, - "codersdk.DERP": { - "type": "object", - "properties": { - "config": { - "$ref": "#/definitions/codersdk.DERPConfig" - }, - "server": { - "$ref": "#/definitions/codersdk.DERPServerConfig" - } - } + "username": { + "type": "string" + } + } + }, + "codersdk.UserStatus": { + "type": "string", + "enum": ["active", "suspended"], + "x-enum-varnames": ["UserStatusActive", "UserStatusSuspended"] + }, + "codersdk.ValidationError": { + "type": "object", + "required": ["detail", "field"], + "properties": { + "detail": { + "type": "string" + }, + "field": { + "type": "string" + } + } + }, + "codersdk.ValidationMonotonicOrder": { + "type": "string", + "enum": ["increasing", "decreasing"], + "x-enum-varnames": [ + "MonotonicOrderIncreasing", + "MonotonicOrderDecreasing" + ] + }, + "codersdk.VariableValue": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.Workspace": { + "type": "object", + "properties": { + "autostart_schedule": { + "type": "string" }, - "codersdk.DERPConfig": { - "type": "object", - "properties": { - "path": { - "type": "string" - }, - "url": { - "type": "string" - } - } + "created_at": { + "type": "string", + "format": "date-time" }, - "codersdk.DERPRegion": { - "type": "object", - "properties": { - "latency_ms": { - "type": "number" - }, - "preferred": { - "type": "boolean" - } - } + "id": { + "type": "string", + "format": "uuid" }, - "codersdk.DERPServerConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - }, - "region_code": { - "type": "string" - }, - "region_id": { - "type": "integer" - }, - "region_name": { - "type": "string" - }, - "relay_url": { - "$ref": "#/definitions/clibase.URL" - }, - "stun_addresses": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.DangerousConfig": { - "type": "object", - "properties": { - "allow_path_app_sharing": { - "type": "boolean" - }, - "allow_path_app_site_owner_access": { - "type": "boolean" - } - } + "last_used_at": { + "type": "string", + "format": "date-time" }, - "codersdk.DeploymentConfig": { - "type": "object", - "properties": { - "config": { - "$ref": "#/definitions/codersdk.DeploymentValues" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/clibase.Option" - } - } - } - }, - "codersdk.DeploymentDAUsResponse": { - "type": "object", - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.DAUEntry" - } - } - } + "latest_build": { + "$ref": "#/definitions/codersdk.WorkspaceBuild" }, - "codersdk.DeploymentStats": { - "type": "object", - "properties": { - "aggregated_from": { - "description": "AggregatedFrom is the time in which stats are aggregated from.\nThis might be back in time a specific duration or interval.", - "type": "string", - "format": "date-time" - }, - "collected_at": { - "description": "CollectedAt is the time in which stats are collected at.", - "type": "string", - "format": "date-time" - }, - "next_update_at": { - "description": "NextUpdateAt is the time when the next batch of stats will\nbe updated.", - "type": "string", - "format": "date-time" - }, - "session_count": { - "$ref": "#/definitions/codersdk.SessionCountDeploymentStats" - }, - "workspaces": { - "$ref": "#/definitions/codersdk.WorkspaceDeploymentStats" - } - } - }, - "codersdk.DeploymentValues": { - "type": "object", - "properties": { - "access_url": { - "$ref": "#/definitions/clibase.URL" - }, - "address": { - "description": "DEPRECATED: Use HTTPAddress or TLS.Address instead.", - "allOf": [ - { - "$ref": "#/definitions/clibase.HostPort" - } - ] - }, - "agent_fallback_troubleshooting_url": { - "$ref": "#/definitions/clibase.URL" - }, - "agent_stat_refresh_interval": { - "type": "integer" - }, - "audit_logging": { - "type": "boolean" - }, - "autobuild_poll_interval": { - "type": "integer" - }, - "browser_only": { - "type": "boolean" - }, - "cache_directory": { - "type": "string" - }, - "config": { - "type": "string" - }, - "config_ssh": { - "$ref": "#/definitions/codersdk.SSHConfig" - }, - "dangerous": { - "$ref": "#/definitions/codersdk.DangerousConfig" - }, - "derp": { - "$ref": "#/definitions/codersdk.DERP" - }, - "disable_password_auth": { - "type": "boolean" - }, - "disable_path_apps": { - "type": "boolean" - }, - "disable_session_expiry_refresh": { - "type": "boolean" - }, - "experiments": { - "type": "array", - "items": { - "type": "string" - } - }, - "git_auth": { - "$ref": "#/definitions/clibase.Struct-array_codersdk_GitAuthConfig" - }, - "http_address": { - "description": "HTTPAddress is a string because it may be set to zero to disable.", - "type": "string" - }, - "in_memory_database": { - "type": "boolean" - }, - "logging": { - "$ref": "#/definitions/codersdk.LoggingConfig" - }, - "max_session_expiry": { - "type": "integer" - }, - "max_token_lifetime": { - "type": "integer" - }, - "metrics_cache_refresh_interval": { - "type": "integer" - }, - "oauth2": { - "$ref": "#/definitions/codersdk.OAuth2Config" - }, - "oidc": { - "$ref": "#/definitions/codersdk.OIDCConfig" - }, - "pg_connection_url": { - "type": "string" - }, - "pprof": { - "$ref": "#/definitions/codersdk.PprofConfig" - }, - "prometheus": { - "$ref": "#/definitions/codersdk.PrometheusConfig" - }, - "provisioner": { - "$ref": "#/definitions/codersdk.ProvisionerConfig" - }, - "proxy_trusted_headers": { - "type": "array", - "items": { - "type": "string" - } - }, - "proxy_trusted_origins": { - "type": "array", - "items": { - "type": "string" - } - }, - "rate_limit": { - "$ref": "#/definitions/codersdk.RateLimitConfig" - }, - "redirect_to_access_url": { - "type": "boolean" - }, - "scim_api_key": { - "type": "string" - }, - "secure_auth_cookie": { - "type": "boolean" - }, - "ssh_keygen_algorithm": { - "type": "string" - }, - "strict_transport_security": { - "type": "integer" - }, - "strict_transport_security_options": { - "type": "array", - "items": { - "type": "string" - } - }, - "support": { - "$ref": "#/definitions/codersdk.SupportConfig" - }, - "swagger": { - "$ref": "#/definitions/codersdk.SwaggerConfig" - }, - "telemetry": { - "$ref": "#/definitions/codersdk.TelemetryConfig" - }, - "tls": { - "$ref": "#/definitions/codersdk.TLSConfig" - }, - "trace": { - "$ref": "#/definitions/codersdk.TraceConfig" - }, - "update_check": { - "type": "boolean" - }, - "verbose": { - "type": "boolean" - }, - "wildcard_access_url": { - "$ref": "#/definitions/clibase.URL" - }, - "write_config": { - "type": "boolean" - } - } - }, - "codersdk.Entitlement": { - "type": "string", - "enum": [ - "entitled", - "grace_period", - "not_entitled" - ], - "x-enum-varnames": [ - "EntitlementEntitled", - "EntitlementGracePeriod", - "EntitlementNotEntitled" - ] + "name": { + "type": "string" }, - "codersdk.Entitlements": { - "type": "object", - "properties": { - "errors": { - "type": "array", - "items": { - "type": "string" - } - }, - "features": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.Feature" - } - }, - "has_license": { - "type": "boolean" - }, - "require_telemetry": { - "type": "boolean" - }, - "trial": { - "type": "boolean" - }, - "warnings": { - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.Experiment": { - "type": "string", - "enum": [ - "authz_querier", - "template_editor" - ], - "x-enum-varnames": [ - "ExperimentAuthzQuerier", - "ExperimentTemplateEditor" - ] + "organization_id": { + "type": "string", + "format": "uuid" }, - "codersdk.Feature": { - "type": "object", - "properties": { - "actual": { - "type": "integer" - }, - "enabled": { - "type": "boolean" - }, - "entitlement": { - "$ref": "#/definitions/codersdk.Entitlement" - }, - "limit": { - "type": "integer" - } - } - }, - "codersdk.GenerateAPIKeyResponse": { - "type": "object", - "properties": { - "key": { - "type": "string" - } - } + "outdated": { + "type": "boolean" }, - "codersdk.GetUsersResponse": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "users": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.User" - } - } - } - }, - "codersdk.GitAuthConfig": { - "type": "object", - "properties": { - "auth_url": { - "type": "string" - }, - "client_id": { - "type": "string" - }, - "id": { - "type": "string" - }, - "no_refresh": { - "type": "boolean" - }, - "regex": { - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - }, - "token_url": { - "type": "string" - }, - "type": { - "type": "string" - }, - "validate_url": { - "type": "string" - } - } - }, - "codersdk.GitProvider": { - "type": "string", - "enum": [ - "azure-devops", - "github", - "gitlab", - "bitbucket" - ], - "x-enum-varnames": [ - "GitProviderAzureDevops", - "GitProviderGitHub", - "GitProviderGitLab", - "GitProviderBitBucket" - ] - }, - "codersdk.GitSSHKey": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "public_key": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.Group": { - "type": "object", - "properties": { - "avatar_url": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "members": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.User" - } - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "quota_allowance": { - "type": "integer" - } - } - }, - "codersdk.Healthcheck": { - "type": "object", - "properties": { - "interval": { - "description": "Interval specifies the seconds between each health check.", - "type": "integer" - }, - "threshold": { - "description": "Threshold specifies the number of consecutive failed health checks before returning \"unhealthy\".", - "type": "integer" - }, - "url": { - "description": "URL specifies the endpoint to check for the app health.", - "type": "string" - } - } - }, - "codersdk.JobErrorCode": { - "type": "string", - "enum": [ - "MISSING_TEMPLATE_PARAMETER", - "REQUIRED_TEMPLATE_VARIABLES" - ], - "x-enum-varnames": [ - "MissingTemplateParameter", - "RequiredTemplateVariables" - ] + "owner_id": { + "type": "string", + "format": "uuid" }, - "codersdk.License": { - "type": "object", - "properties": { - "claims": { - "description": "Claims are the JWT claims asserted by the license. Here we use\na generic string map to ensure that all data from the server is\nparsed verbatim, not just the fields this version of Coder\nunderstands.", - "type": "object", - "additionalProperties": true - }, - "id": { - "type": "integer" - }, - "uploaded_at": { - "type": "string", - "format": "date-time" - }, - "uuid": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.LinkConfig": { - "type": "object", - "properties": { - "icon": { - "type": "string" - }, - "name": { - "type": "string" - }, - "target": { - "type": "string" - } - } + "owner_name": { + "type": "string" }, - "codersdk.LogLevel": { - "type": "string", - "enum": [ - "trace", - "debug", - "info", - "warn", - "error" - ], - "x-enum-varnames": [ - "LogLevelTrace", - "LogLevelDebug", - "LogLevelInfo", - "LogLevelWarn", - "LogLevelError" - ] + "template_allow_user_cancel_workspace_jobs": { + "type": "boolean" }, - "codersdk.LogSource": { - "type": "string", - "enum": [ - "provisioner_daemon", - "provisioner" - ], - "x-enum-varnames": [ - "LogSourceProvisionerDaemon", - "LogSourceProvisioner" - ] + "template_display_name": { + "type": "string" }, - "codersdk.LoggingConfig": { - "type": "object", - "properties": { - "human": { - "type": "string" - }, - "json": { - "type": "string" - }, - "stackdriver": { - "type": "string" - } - } + "template_icon": { + "type": "string" }, - "codersdk.LoginType": { - "type": "string", - "enum": [ - "password", - "github", - "oidc", - "token" - ], - "x-enum-varnames": [ - "LoginTypePassword", - "LoginTypeGithub", - "LoginTypeOIDC", - "LoginTypeToken" - ] - }, - "codersdk.LoginWithPasswordRequest": { - "type": "object", - "required": [ - "email", - "password" - ], - "properties": { - "email": { - "type": "string", - "format": "email" - }, - "password": { - "type": "string" - } - } + "template_id": { + "type": "string", + "format": "uuid" }, - "codersdk.LoginWithPasswordResponse": { - "type": "object", - "required": [ - "session_token" - ], - "properties": { - "session_token": { - "type": "string" - } - } + "template_name": { + "type": "string" }, - "codersdk.OAuth2Config": { - "type": "object", - "properties": { - "github": { - "$ref": "#/definitions/codersdk.OAuth2GithubConfig" - } - } + "ttl_ms": { + "type": "integer" }, - "codersdk.OAuth2GithubConfig": { - "type": "object", - "properties": { - "allow_everyone": { - "type": "boolean" - }, - "allow_signups": { - "type": "boolean" - }, - "allowed_orgs": { - "type": "array", - "items": { - "type": "string" - } - }, - "allowed_teams": { - "type": "array", - "items": { - "type": "string" - } - }, - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - }, - "enterprise_base_url": { - "type": "string" - } - } - }, - "codersdk.OIDCAuthMethod": { - "type": "object", - "properties": { - "enabled": { - "type": "boolean" - }, - "iconUrl": { - "type": "string" - }, - "signInText": { - "type": "string" - } - } - }, - "codersdk.OIDCConfig": { - "type": "object", - "properties": { - "allow_signups": { - "type": "boolean" - }, - "client_id": { - "type": "string" - }, - "client_secret": { - "type": "string" - }, - "email_domain": { - "type": "array", - "items": { - "type": "string" - } - }, - "groups_field": { - "type": "string" - }, - "icon_url": { - "$ref": "#/definitions/clibase.URL" - }, - "ignore_email_verified": { - "type": "boolean" - }, - "issuer_url": { - "type": "string" - }, - "scopes": { - "type": "array", - "items": { - "type": "string" - } - }, - "sign_in_text": { - "type": "string" - }, - "username_field": { - "type": "string" - } - } - }, - "codersdk.Organization": { - "type": "object", - "required": [ - "created_at", - "id", - "name", - "updated_at" - ], - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.OrganizationMember": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "user_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.Parameter": { - "description": "Parameter represents a set value for the scope.", - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "destination_scheme": { - "enum": [ - "none", - "environment_variable", - "provisioner_variable" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterDestinationScheme" - } - ] - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "scope": { - "enum": [ - "template", - "workspace", - "import_job" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterScope" - } - ] - }, - "scope_id": { - "type": "string", - "format": "uuid" - }, - "source_scheme": { - "enum": [ - "none", - "data" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterSourceScheme" - } - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.ParameterDestinationScheme": { - "type": "string", - "enum": [ - "none", - "environment_variable", - "provisioner_variable" - ], - "x-enum-varnames": [ - "ParameterDestinationSchemeNone", - "ParameterDestinationSchemeEnvironmentVariable", - "ParameterDestinationSchemeProvisionerVariable" - ] + "updated_at": { + "type": "string", + "format": "date-time" + } + } + }, + "codersdk.WorkspaceAgent": { + "type": "object", + "properties": { + "apps": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceApp" + } }, - "codersdk.ParameterSchema": { - "type": "object", - "properties": { - "allow_override_destination": { - "type": "boolean" - }, - "allow_override_source": { - "type": "boolean" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "default_destination_scheme": { - "enum": [ - "none", - "environment_variable", - "provisioner_variable" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterDestinationScheme" - } - ] - }, - "default_refresh": { - "type": "string" - }, - "default_source_scheme": { - "enum": [ - "none", - "data" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ParameterSourceScheme" - } - ] - }, - "default_source_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job_id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "redisplay_value": { - "type": "boolean" - }, - "validation_condition": { - "type": "string" - }, - "validation_contains": { - "description": "This is a special array of items provided if the validation condition\nexplicitly states the value must be one of a set.", - "type": "array", - "items": { - "type": "string" - } - }, - "validation_error": { - "type": "string" - }, - "validation_type_system": { - "type": "string" - }, - "validation_value_type": { - "type": "string" - } - } - }, - "codersdk.ParameterScope": { - "type": "string", - "enum": [ - "template", - "workspace", - "import_job" - ], - "x-enum-varnames": [ - "ParameterTemplate", - "ParameterWorkspace", - "ParameterImportJob" - ] + "architecture": { + "type": "string" }, - "codersdk.ParameterSourceScheme": { - "type": "string", - "enum": [ - "none", - "data" - ], - "x-enum-varnames": [ - "ParameterSourceSchemeNone", - "ParameterSourceSchemeData" - ] + "connection_timeout_seconds": { + "type": "integer" }, - "codersdk.PprofConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/clibase.HostPort" - }, - "enable": { - "type": "boolean" - } - } + "created_at": { + "type": "string", + "format": "date-time" }, - "codersdk.PrometheusConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/clibase.HostPort" - }, - "enable": { - "type": "boolean" - } - } + "directory": { + "type": "string" }, - "codersdk.ProvisionerConfig": { - "type": "object", - "properties": { - "daemon_poll_interval": { - "type": "integer" - }, - "daemon_poll_jitter": { - "type": "integer" - }, - "daemons": { - "type": "integer" - }, - "force_cancel_interval": { - "type": "integer" - } - } - }, - "codersdk.ProvisionerDaemon": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "name": { - "type": "string" - }, - "provisioners": { - "type": "array", - "items": { - "type": "string" - } - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "updated_at": { - "format": "date-time", - "allOf": [ - { - "$ref": "#/definitions/sql.NullTime" - } - ] - } - } - }, - "codersdk.ProvisionerJob": { - "type": "object", - "properties": { - "canceled_at": { - "type": "string", - "format": "date-time" - }, - "completed_at": { - "type": "string", - "format": "date-time" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "error": { - "type": "string" - }, - "error_code": { - "enum": [ - "MISSING_TEMPLATE_PARAMETER", - "REQUIRED_TEMPLATE_VARIABLES" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.JobErrorCode" - } - ] - }, - "file_id": { - "type": "string", - "format": "uuid" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "started_at": { - "type": "string", - "format": "date-time" - }, - "status": { - "enum": [ - "pending", - "running", - "succeeded", - "canceling", - "canceled", - "failed" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ProvisionerJobStatus" - } - ] - }, - "tags": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "worker_id": { - "type": "string", - "format": "uuid" - } - } - }, - "codersdk.ProvisionerJobLog": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "integer" - }, - "log_level": { - "enum": [ - "trace", - "debug", - "info", - "warn", - "error" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.LogLevel" - } - ] - }, - "log_source": { - "$ref": "#/definitions/codersdk.LogSource" - }, - "output": { - "type": "string" - }, - "stage": { - "type": "string" - } - } - }, - "codersdk.ProvisionerJobStatus": { - "type": "string", - "enum": [ - "pending", - "running", - "succeeded", - "canceling", - "canceled", - "failed" - ], - "x-enum-varnames": [ - "ProvisionerJobPending", - "ProvisionerJobRunning", - "ProvisionerJobSucceeded", - "ProvisionerJobCanceling", - "ProvisionerJobCanceled", - "ProvisionerJobFailed" - ] + "disconnected_at": { + "type": "string", + "format": "date-time" }, - "codersdk.ProvisionerStorageMethod": { - "type": "string", - "enum": [ - "file" - ], - "x-enum-varnames": [ - "ProvisionerStorageMethodFile" - ] + "environment_variables": { + "type": "object", + "additionalProperties": { + "type": "string" + } }, - "codersdk.PutExtendWorkspaceRequest": { - "type": "object", - "required": [ - "deadline" - ], - "properties": { - "deadline": { - "type": "string", - "format": "date-time" - } - } + "expanded_directory": { + "type": "string" }, - "codersdk.RateLimitConfig": { - "type": "object", - "properties": { - "api": { - "type": "integer" - }, - "disable_all": { - "type": "boolean" - } - } + "first_connected_at": { + "type": "string", + "format": "date-time" }, - "codersdk.Replica": { - "type": "object", - "properties": { - "created_at": { - "description": "CreatedAt is the timestamp when the replica was first seen.", - "type": "string", - "format": "date-time" - }, - "database_latency": { - "description": "DatabaseLatency is the latency in microseconds to the database.", - "type": "integer" - }, - "error": { - "description": "Error is the replica error.", - "type": "string" - }, - "hostname": { - "description": "Hostname is the hostname of the replica.", - "type": "string" - }, - "id": { - "description": "ID is the unique identifier for the replica.", - "type": "string", - "format": "uuid" - }, - "region_id": { - "description": "RegionID is the region of the replica.", - "type": "integer" - }, - "relay_address": { - "description": "RelayAddress is the accessible address to relay DERP connections.", - "type": "string" - } - } - }, - "codersdk.ResourceType": { - "type": "string", - "enum": [ - "template", - "template_version", - "user", - "workspace", - "workspace_build", - "git_ssh_key", - "api_key", - "group", - "license" - ], - "x-enum-varnames": [ - "ResourceTypeTemplate", - "ResourceTypeTemplateVersion", - "ResourceTypeUser", - "ResourceTypeWorkspace", - "ResourceTypeWorkspaceBuild", - "ResourceTypeGitSSHKey", - "ResourceTypeAPIKey", - "ResourceTypeGroup", - "ResourceTypeLicense" - ] - }, - "codersdk.Response": { - "type": "object", - "properties": { - "detail": { - "description": "Detail is a debug message that provides further insight into why the\naction failed. This information can be technical and a regular golang\nerr.Error() text.\n- \"database: too many open connections\"\n- \"stat: too many open files\"", - "type": "string" - }, - "message": { - "description": "Message is an actionable message that depicts actions the request took.\nThese messages should be fully formed sentences with proper punctuation.\nExamples:\n- \"A user has been created.\"\n- \"Failed to create a user.\"", - "type": "string" - }, - "validations": { - "description": "Validations are form field-specific friendly error messages. They will be\nshown on a form field in the UI. These can also be used to add additional\ncontext if there is a set of errors in the primary 'Message'.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.ValidationError" - } - } - } - }, - "codersdk.Role": { - "type": "object", - "properties": { - "display_name": { - "type": "string" - }, - "name": { - "type": "string" - } - } + "id": { + "type": "string", + "format": "uuid" }, - "codersdk.SSHConfig": { - "type": "object", - "properties": { - "deploymentName": { - "description": "DeploymentName is the config-ssh Hostname prefix", - "type": "string" - }, - "sshconfigOptions": { - "description": "SSHConfigOptions are additional options to add to the ssh config file.\nThis will override defaults.", - "type": "array", - "items": { - "type": "string" - } - } - } - }, - "codersdk.SSHConfigResponse": { - "type": "object", - "properties": { - "hostname_prefix": { - "type": "string" - }, - "ssh_config_options": { - "type": "object", - "additionalProperties": { - "type": "string" - } - } - } - }, - "codersdk.ServiceBannerConfig": { - "type": "object", - "properties": { - "background_color": { - "type": "string" - }, - "enabled": { - "type": "boolean" - }, - "message": { - "type": "string" - } - } - }, - "codersdk.SessionCountDeploymentStats": { - "type": "object", - "properties": { - "jetbrains": { - "type": "integer" - }, - "reconnecting_pty": { - "type": "integer" - }, - "ssh": { - "type": "integer" - }, - "vscode": { - "type": "integer" - } - } - }, - "codersdk.SupportConfig": { - "type": "object", - "properties": { - "links": { - "$ref": "#/definitions/clibase.Struct-array_codersdk_LinkConfig" - } - } + "instance_id": { + "type": "string" }, - "codersdk.SwaggerConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - } - } + "last_connected_at": { + "type": "string", + "format": "date-time" }, - "codersdk.TLSConfig": { - "type": "object", - "properties": { - "address": { - "$ref": "#/definitions/clibase.HostPort" - }, - "cert_file": { - "type": "array", - "items": { - "type": "string" - } - }, - "client_auth": { - "type": "string" - }, - "client_ca_file": { - "type": "string" - }, - "client_cert_file": { - "type": "string" - }, - "client_key_file": { - "type": "string" - }, - "enable": { - "type": "boolean" - }, - "key_file": { - "type": "array", - "items": { - "type": "string" - } - }, - "min_version": { - "type": "string" - }, - "redirect_http": { - "type": "boolean" - } - } - }, - "codersdk.TelemetryConfig": { - "type": "object", - "properties": { - "enable": { - "type": "boolean" - }, - "trace": { - "type": "boolean" - }, - "url": { - "$ref": "#/definitions/clibase.URL" - } - } - }, - "codersdk.Template": { - "type": "object", - "properties": { - "active_user_count": { - "description": "ActiveUserCount is set to -1 when loading.", - "type": "integer" - }, - "active_version_id": { - "type": "string", - "format": "uuid" - }, - "allow_user_cancel_workspace_jobs": { - "type": "boolean" - }, - "build_time_stats": { - "$ref": "#/definitions/codersdk.TemplateBuildTimeStats" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "created_by_id": { - "type": "string", - "format": "uuid" - }, - "created_by_name": { - "type": "string" - }, - "default_ttl_ms": { - "type": "integer" - }, - "description": { - "type": "string" - }, - "display_name": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "max_ttl_ms": { - "description": "MaxTTLMillis is an enterprise feature. It's value is only used if your\nlicense is entitled to use the advanced template scheduling feature.", - "type": "integer" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "provisioner": { - "type": "string", - "enum": [ - "terraform" - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.TemplateBuildTimeStats": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TransitionStats" - } + "latency": { + "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/codersdk.DERPRegion" + } }, - "codersdk.TemplateDAUsResponse": { - "type": "object", - "properties": { - "entries": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.DAUEntry" - } - } - } + "lifecycle_state": { + "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" }, - "codersdk.TemplateExample": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "markdown": { - "type": "string" - }, - "name": { - "type": "string" - }, - "tags": { - "type": "array", - "items": { - "type": "string" - } - }, - "url": { - "type": "string" - } - } - }, - "codersdk.TemplateRole": { - "type": "string", - "enum": [ - "admin", - "use", - "" - ], - "x-enum-varnames": [ - "TemplateRoleAdmin", - "TemplateRoleUse", - "TemplateRoleDeleted" - ] + "login_before_ready": { + "description": "LoginBeforeReady if true, the agent will delay logins until it is ready (e.g. executing startup script has ended).", + "type": "boolean" }, - "codersdk.TemplateUser": { - "type": "object", - "required": [ - "created_at", - "email", - "id", - "username" - ], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "organization_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "role": { - "enum": [ - "admin", - "use" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.TemplateRole" - } - ] - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - }, - "status": { - "enum": [ - "active", - "suspended" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" - } - ] - }, - "username": { - "type": "string" - } - } - }, - "codersdk.TemplateVersion": { - "type": "object", - "properties": { - "created_at": { - "type": "string", - "format": "date-time" - }, - "created_by": { - "$ref": "#/definitions/codersdk.User" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "readme": { - "type": "string" - }, - "template_id": { - "type": "string", - "format": "uuid" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.TemplateVersionGitAuth": { - "type": "object", - "properties": { - "authenticate_url": { - "type": "string" - }, - "authenticated": { - "type": "boolean" - }, - "id": { - "type": "string" - }, - "type": { - "$ref": "#/definitions/codersdk.GitProvider" - } - } - }, - "codersdk.TemplateVersionParameter": { - "type": "object", - "properties": { - "default_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "description_plaintext": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "legacy_variable_name": { - "type": "string" - }, - "mutable": { - "type": "boolean" - }, - "name": { - "type": "string" - }, - "options": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.TemplateVersionParameterOption" - } - }, - "required": { - "type": "boolean" - }, - "type": { - "type": "string", - "enum": [ - "string", - "number", - "bool", - "list(string)" - ] - }, - "validation_error": { - "type": "string" - }, - "validation_max": { - "type": "integer" - }, - "validation_min": { - "type": "integer" - }, - "validation_monotonic": { - "enum": [ - "increasing", - "decreasing" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.ValidationMonotonicOrder" - } - ] - }, - "validation_regex": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionParameterOption": { - "type": "object", - "properties": { - "description": { - "type": "string" - }, - "icon": { - "type": "string" - }, - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } - }, - "codersdk.TemplateVersionVariable": { - "type": "object", - "properties": { - "default_value": { - "type": "string" - }, - "description": { - "type": "string" - }, - "name": { - "type": "string" - }, - "required": { - "type": "boolean" - }, - "sensitive": { - "type": "boolean" - }, - "type": { - "type": "string", - "enum": [ - "string", - "number", - "bool" - ] - }, - "value": { - "type": "string" - } - } - }, - "codersdk.TokenConfig": { - "type": "object", - "properties": { - "max_token_lifetime": { - "type": "integer" - } - } + "name": { + "type": "string" }, - "codersdk.TraceConfig": { - "type": "object", - "properties": { - "capture_logs": { - "type": "boolean" - }, - "enable": { - "type": "boolean" - }, - "honeycomb_api_key": { - "type": "string" - } - } - }, - "codersdk.TransitionStats": { - "type": "object", - "properties": { - "p50": { - "type": "integer", - "example": 123 - }, - "p95": { - "type": "integer", - "example": 146 - } - } + "operating_system": { + "type": "string" }, - "codersdk.UpdateActiveTemplateVersion": { - "type": "object", - "required": [ - "id" - ], - "properties": { - "id": { - "type": "string", - "format": "uuid" - } - } + "resource_id": { + "type": "string", + "format": "uuid" }, - "codersdk.UpdateAppearanceConfig": { - "type": "object", - "properties": { - "logo_url": { - "type": "string" - }, - "service_banner": { - "$ref": "#/definitions/codersdk.ServiceBannerConfig" - } - } + "shutdown_script": { + "type": "string" }, - "codersdk.UpdateCheckResponse": { - "type": "object", - "properties": { - "current": { - "description": "Current indicates whether the server version is the same as the latest.", - "type": "boolean" - }, - "url": { - "description": "URL to download the latest release of Coder.", - "type": "string" - }, - "version": { - "description": "Version is the semantic version for the latest release of Coder.", - "type": "string" - } - } - }, - "codersdk.UpdateRoles": { - "type": "object", - "properties": { - "roles": { - "type": "array", - "items": { - "type": "string" - } - } - } + "shutdown_script_timeout_seconds": { + "type": "integer" }, - "codersdk.UpdateTemplateACL": { - "type": "object", - "properties": { - "group_perms": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TemplateRole" - } - }, - "user_perms": { - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.TemplateRole" - } - } - } - }, - "codersdk.UpdateUserPasswordRequest": { - "type": "object", - "required": [ - "password" - ], - "properties": { - "old_password": { - "type": "string" - }, - "password": { - "type": "string" - } - } + "startup_script": { + "type": "string" }, - "codersdk.UpdateUserProfileRequest": { - "type": "object", - "required": [ - "username" - ], - "properties": { - "username": { - "type": "string" - } - } + "startup_script_timeout_seconds": { + "description": "StartupScriptTimeoutSeconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout.", + "type": "integer" }, - "codersdk.UpdateWorkspaceAutostartRequest": { - "type": "object", - "properties": { - "schedule": { - "type": "string" - } - } + "status": { + "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" }, - "codersdk.UpdateWorkspaceRequest": { - "type": "object", - "properties": { - "name": { - "type": "string" - } - } + "troubleshooting_url": { + "type": "string" }, - "codersdk.UpdateWorkspaceTTLRequest": { - "type": "object", - "properties": { - "ttl_ms": { - "type": "integer" - } - } + "updated_at": { + "type": "string", + "format": "date-time" }, - "codersdk.UploadResponse": { - "type": "object", - "properties": { - "hash": { - "type": "string", - "format": "uuid" - } - } + "version": { + "type": "string" + } + } + }, + "codersdk.WorkspaceAgentConnectionInfo": { + "type": "object", + "properties": { + "derp_map": { + "$ref": "#/definitions/tailcfg.DERPMap" + } + } + }, + "codersdk.WorkspaceAgentLifecycle": { + "type": "string", + "enum": [ + "created", + "starting", + "start_timeout", + "start_error", + "ready", + "shutting_down", + "shutdown_timeout", + "shutdown_error", + "off" + ], + "x-enum-varnames": [ + "WorkspaceAgentLifecycleCreated", + "WorkspaceAgentLifecycleStarting", + "WorkspaceAgentLifecycleStartTimeout", + "WorkspaceAgentLifecycleStartError", + "WorkspaceAgentLifecycleReady", + "WorkspaceAgentLifecycleShuttingDown", + "WorkspaceAgentLifecycleShutdownTimeout", + "WorkspaceAgentLifecycleShutdownError", + "WorkspaceAgentLifecycleOff" + ] + }, + "codersdk.WorkspaceAgentListeningPort": { + "type": "object", + "properties": { + "network": { + "description": "only \"tcp\" at the moment", + "type": "string" + }, + "port": { + "type": "integer" + }, + "process_name": { + "description": "may be empty", + "type": "string" + } + } + }, + "codersdk.WorkspaceAgentListeningPortsResponse": { + "type": "object", + "properties": { + "ports": { + "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPort" + } + } + } + }, + "codersdk.WorkspaceAgentStatus": { + "type": "string", + "enum": ["connecting", "connected", "disconnected", "timeout"], + "x-enum-varnames": [ + "WorkspaceAgentConnecting", + "WorkspaceAgentConnected", + "WorkspaceAgentDisconnected", + "WorkspaceAgentTimeout" + ] + }, + "codersdk.WorkspaceApp": { + "type": "object", + "properties": { + "command": { + "type": "string" + }, + "display_name": { + "description": "DisplayName is a friendly name for the app.", + "type": "string" + }, + "external": { + "description": "External specifies whether the URL should be opened externally on\nthe client or not.", + "type": "boolean" + }, + "health": { + "$ref": "#/definitions/codersdk.WorkspaceAppHealth" + }, + "healthcheck": { + "description": "Healthcheck specifies the configuration for checking app health.", + "allOf": [ + { + "$ref": "#/definitions/codersdk.Healthcheck" + } + ] + }, + "icon": { + "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "sharing_level": { + "enum": ["owner", "authenticated", "public"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceAppSharingLevel" + } + ] + }, + "slug": { + "description": "Slug is a unique identifier within the agent.", + "type": "string" + }, + "subdomain": { + "description": "Subdomain denotes whether the app should be accessed via a path on the\n`coder server` or via a hostname-based dev URL. If this is set to true\nand there is no app wildcard configured on the server, the app will not\nbe accessible in the UI.", + "type": "boolean" + }, + "url": { + "description": "URL is the address being proxied to inside the workspace.\nIf external is specified, this will be opened on the client.", + "type": "string" + } + } + }, + "codersdk.WorkspaceAppHealth": { + "type": "string", + "enum": ["disabled", "initializing", "healthy", "unhealthy"], + "x-enum-varnames": [ + "WorkspaceAppHealthDisabled", + "WorkspaceAppHealthInitializing", + "WorkspaceAppHealthHealthy", + "WorkspaceAppHealthUnhealthy" + ] + }, + "codersdk.WorkspaceAppSharingLevel": { + "type": "string", + "enum": ["owner", "authenticated", "public"], + "x-enum-varnames": [ + "WorkspaceAppSharingLevelOwner", + "WorkspaceAppSharingLevelAuthenticated", + "WorkspaceAppSharingLevelPublic" + ] + }, + "codersdk.WorkspaceBuild": { + "type": "object", + "properties": { + "build_number": { + "type": "integer" + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "daily_cost": { + "type": "integer" + }, + "deadline": { + "type": "string", + "format": "date-time" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "initiator_id": { + "type": "string", + "format": "uuid" + }, + "initiator_name": { + "type": "string" + }, + "job": { + "$ref": "#/definitions/codersdk.ProvisionerJob" + }, + "max_deadline": { + "type": "string", + "format": "date-time" + }, + "reason": { + "enum": ["initiator", "autostart", "autostop"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.BuildReason" + } + ] + }, + "resources": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResource" + } + }, + "status": { + "enum": [ + "pending", + "starting", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleting", + "deleted" + ], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceStatus" + } + ] + }, + "template_version_id": { + "type": "string", + "format": "uuid" + }, + "template_version_name": { + "type": "string" + }, + "transition": { + "enum": ["start", "stop", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + }, + "updated_at": { + "type": "string", + "format": "date-time" + }, + "workspace_id": { + "type": "string", + "format": "uuid" + }, + "workspace_name": { + "type": "string" + }, + "workspace_owner_id": { + "type": "string", + "format": "uuid" + }, + "workspace_owner_name": { + "type": "string" + } + } + }, + "codersdk.WorkspaceBuildParameter": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "codersdk.WorkspaceConnectionLatencyMS": { + "type": "object", + "properties": { + "p50": { + "type": "number" + }, + "p95": { + "type": "number" + } + } + }, + "codersdk.WorkspaceDeploymentStats": { + "type": "object", + "properties": { + "building": { + "type": "integer" }, - "codersdk.User": { - "type": "object", - "required": [ - "created_at", - "email", - "id", - "username" - ], - "properties": { - "avatar_url": { - "type": "string", - "format": "uri" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "email": { - "type": "string", - "format": "email" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_seen_at": { - "type": "string", - "format": "date-time" - }, - "organization_ids": { - "type": "array", - "items": { - "type": "string", - "format": "uuid" - } - }, - "roles": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Role" - } - }, - "status": { - "enum": [ - "active", - "suspended" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.UserStatus" - } - ] - }, - "username": { - "type": "string" - } - } - }, - "codersdk.UserStatus": { - "type": "string", - "enum": [ - "active", - "suspended" - ], - "x-enum-varnames": [ - "UserStatusActive", - "UserStatusSuspended" - ] + "connection_latency_ms": { + "$ref": "#/definitions/codersdk.WorkspaceConnectionLatencyMS" }, - "codersdk.ValidationError": { - "type": "object", - "required": [ - "detail", - "field" - ], - "properties": { - "detail": { - "type": "string" - }, - "field": { - "type": "string" - } - } + "failed": { + "type": "integer" }, - "codersdk.ValidationMonotonicOrder": { - "type": "string", - "enum": [ - "increasing", - "decreasing" - ], - "x-enum-varnames": [ - "MonotonicOrderIncreasing", - "MonotonicOrderDecreasing" - ] + "pending": { + "type": "integer" }, - "codersdk.VariableValue": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } + "running": { + "type": "integer" }, - "codersdk.Workspace": { - "type": "object", - "properties": { - "autostart_schedule": { - "type": "string" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "last_used_at": { - "type": "string", - "format": "date-time" - }, - "latest_build": { - "$ref": "#/definitions/codersdk.WorkspaceBuild" - }, - "name": { - "type": "string" - }, - "organization_id": { - "type": "string", - "format": "uuid" - }, - "outdated": { - "type": "boolean" - }, - "owner_id": { - "type": "string", - "format": "uuid" - }, - "owner_name": { - "type": "string" - }, - "template_allow_user_cancel_workspace_jobs": { - "type": "boolean" - }, - "template_display_name": { - "type": "string" - }, - "template_icon": { - "type": "string" - }, - "template_id": { - "type": "string", - "format": "uuid" - }, - "template_name": { - "type": "string" - }, - "ttl_ms": { - "type": "integer" - }, - "updated_at": { - "type": "string", - "format": "date-time" - } - } - }, - "codersdk.WorkspaceAgent": { - "type": "object", - "properties": { - "apps": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceApp" - } - }, - "architecture": { - "type": "string" - }, - "connection_timeout_seconds": { - "type": "integer" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "directory": { - "type": "string" - }, - "disconnected_at": { - "type": "string", - "format": "date-time" - }, - "environment_variables": { - "type": "object", - "additionalProperties": { - "type": "string" - } - }, - "expanded_directory": { - "type": "string" - }, - "first_connected_at": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "instance_id": { - "type": "string" - }, - "last_connected_at": { - "type": "string", - "format": "date-time" - }, - "latency": { - "description": "DERPLatency is mapped by region name (e.g. \"New York City\", \"Seattle\").", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/codersdk.DERPRegion" - } - }, - "lifecycle_state": { - "$ref": "#/definitions/codersdk.WorkspaceAgentLifecycle" - }, - "login_before_ready": { - "description": "LoginBeforeReady if true, the agent will delay logins until it is ready (e.g. executing startup script has ended).", - "type": "boolean" - }, - "name": { - "type": "string" - }, - "operating_system": { - "type": "string" - }, - "resource_id": { - "type": "string", - "format": "uuid" - }, - "shutdown_script": { - "type": "string" - }, - "shutdown_script_timeout_seconds": { - "type": "integer" - }, - "startup_script": { - "type": "string" - }, - "startup_script_timeout_seconds": { - "description": "StartupScriptTimeoutSeconds is the number of seconds to wait for the startup script to complete. If the script does not complete within this time, the agent lifecycle will be marked as start_timeout.", - "type": "integer" - }, - "status": { - "$ref": "#/definitions/codersdk.WorkspaceAgentStatus" - }, - "troubleshooting_url": { - "type": "string" - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "version": { - "type": "string" - } - } - }, - "codersdk.WorkspaceAgentConnectionInfo": { - "type": "object", - "properties": { - "derp_map": { - "$ref": "#/definitions/tailcfg.DERPMap" - } - } + "rx_bytes": { + "type": "integer" }, - "codersdk.WorkspaceAgentLifecycle": { - "type": "string", - "enum": [ - "created", - "starting", - "start_timeout", - "start_error", - "ready", - "shutting_down", - "shutdown_timeout", - "shutdown_error", - "off" - ], - "x-enum-varnames": [ - "WorkspaceAgentLifecycleCreated", - "WorkspaceAgentLifecycleStarting", - "WorkspaceAgentLifecycleStartTimeout", - "WorkspaceAgentLifecycleStartError", - "WorkspaceAgentLifecycleReady", - "WorkspaceAgentLifecycleShuttingDown", - "WorkspaceAgentLifecycleShutdownTimeout", - "WorkspaceAgentLifecycleShutdownError", - "WorkspaceAgentLifecycleOff" - ] - }, - "codersdk.WorkspaceAgentListeningPort": { - "type": "object", - "properties": { - "network": { - "description": "only \"tcp\" at the moment", - "type": "string" - }, - "port": { - "type": "integer" - }, - "process_name": { - "description": "may be empty", - "type": "string" - } - } - }, - "codersdk.WorkspaceAgentListeningPortsResponse": { - "type": "object", - "properties": { - "ports": { - "description": "If there are no ports in the list, nothing should be displayed in the UI.\nThere must not be a \"no ports available\" message or anything similar, as\nthere will always be no ports displayed on platforms where our port\ndetection logic is unsupported.", - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgentListeningPort" - } - } - } + "stopped": { + "type": "integer" }, - "codersdk.WorkspaceAgentStatus": { - "type": "string", - "enum": [ - "connecting", - "connected", - "disconnected", - "timeout" - ], - "x-enum-varnames": [ - "WorkspaceAgentConnecting", - "WorkspaceAgentConnected", - "WorkspaceAgentDisconnected", - "WorkspaceAgentTimeout" - ] - }, - "codersdk.WorkspaceApp": { - "type": "object", - "properties": { - "command": { - "type": "string" - }, - "display_name": { - "description": "DisplayName is a friendly name for the app.", - "type": "string" - }, - "external": { - "description": "External specifies whether the URL should be opened externally on\nthe client or not.", - "type": "boolean" - }, - "health": { - "$ref": "#/definitions/codersdk.WorkspaceAppHealth" - }, - "healthcheck": { - "description": "Healthcheck specifies the configuration for checking app health.", - "allOf": [ - { - "$ref": "#/definitions/codersdk.Healthcheck" - } - ] - }, - "icon": { - "description": "Icon is a relative path or external URL that specifies\nan icon to be displayed in the dashboard.", - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "sharing_level": { - "enum": [ - "owner", - "authenticated", - "public" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceAppSharingLevel" - } - ] - }, - "slug": { - "description": "Slug is a unique identifier within the agent.", - "type": "string" - }, - "subdomain": { - "description": "Subdomain denotes whether the app should be accessed via a path on the\n`coder server` or via a hostname-based dev URL. If this is set to true\nand there is no app wildcard configured on the server, the app will not\nbe accessible in the UI.", - "type": "boolean" - }, - "url": { - "description": "URL is the address being proxied to inside the workspace.\nIf external is specified, this will be opened on the client.", - "type": "string" - } - } - }, - "codersdk.WorkspaceAppHealth": { - "type": "string", - "enum": [ - "disabled", - "initializing", - "healthy", - "unhealthy" - ], - "x-enum-varnames": [ - "WorkspaceAppHealthDisabled", - "WorkspaceAppHealthInitializing", - "WorkspaceAppHealthHealthy", - "WorkspaceAppHealthUnhealthy" - ] + "tx_bytes": { + "type": "integer" + } + } + }, + "codersdk.WorkspaceQuota": { + "type": "object", + "properties": { + "budget": { + "type": "integer" + }, + "credits_consumed": { + "type": "integer" + } + } + }, + "codersdk.WorkspaceResource": { + "type": "object", + "properties": { + "agents": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceAgent" + } + }, + "created_at": { + "type": "string", + "format": "date-time" + }, + "daily_cost": { + "type": "integer" + }, + "hide": { + "type": "boolean" + }, + "icon": { + "type": "string" + }, + "id": { + "type": "string", + "format": "uuid" + }, + "job_id": { + "type": "string", + "format": "uuid" + }, + "metadata": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.WorkspaceResourceMetadata" + } + }, + "name": { + "type": "string" + }, + "type": { + "type": "string" + }, + "workspace_transition": { + "enum": ["start", "stop", "delete"], + "allOf": [ + { + "$ref": "#/definitions/codersdk.WorkspaceTransition" + } + ] + } + } + }, + "codersdk.WorkspaceResourceMetadata": { + "type": "object", + "properties": { + "key": { + "type": "string" }, - "codersdk.WorkspaceAppSharingLevel": { - "type": "string", - "enum": [ - "owner", - "authenticated", - "public" - ], - "x-enum-varnames": [ - "WorkspaceAppSharingLevelOwner", - "WorkspaceAppSharingLevelAuthenticated", - "WorkspaceAppSharingLevelPublic" - ] + "sensitive": { + "type": "boolean" }, - "codersdk.WorkspaceBuild": { - "type": "object", - "properties": { - "build_number": { - "type": "integer" - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "daily_cost": { - "type": "integer" - }, - "deadline": { - "type": "string", - "format": "date-time" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "initiator_id": { - "type": "string", - "format": "uuid" - }, - "initiator_name": { - "type": "string" - }, - "job": { - "$ref": "#/definitions/codersdk.ProvisionerJob" - }, - "max_deadline": { - "type": "string", - "format": "date-time" - }, - "reason": { - "enum": [ - "initiator", - "autostart", - "autostop" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.BuildReason" - } - ] - }, - "resources": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResource" - } - }, - "status": { - "enum": [ - "pending", - "starting", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleting", - "deleted" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceStatus" - } - ] - }, - "template_version_id": { - "type": "string", - "format": "uuid" - }, - "template_version_name": { - "type": "string" - }, - "transition": { - "enum": [ - "start", - "stop", - "delete" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - }, - "updated_at": { - "type": "string", - "format": "date-time" - }, - "workspace_id": { - "type": "string", - "format": "uuid" - }, - "workspace_name": { - "type": "string" - }, - "workspace_owner_id": { - "type": "string", - "format": "uuid" - }, - "workspace_owner_name": { - "type": "string" - } - } - }, - "codersdk.WorkspaceBuildParameter": { - "type": "object", - "properties": { - "name": { - "type": "string" - }, - "value": { - "type": "string" - } - } + "value": { + "type": "string" + } + } + }, + "codersdk.WorkspaceStatus": { + "type": "string", + "enum": [ + "pending", + "starting", + "running", + "stopping", + "stopped", + "failed", + "canceling", + "canceled", + "deleting", + "deleted" + ], + "x-enum-varnames": [ + "WorkspaceStatusPending", + "WorkspaceStatusStarting", + "WorkspaceStatusRunning", + "WorkspaceStatusStopping", + "WorkspaceStatusStopped", + "WorkspaceStatusFailed", + "WorkspaceStatusCanceling", + "WorkspaceStatusCanceled", + "WorkspaceStatusDeleting", + "WorkspaceStatusDeleted" + ] + }, + "codersdk.WorkspaceTransition": { + "type": "string", + "enum": ["start", "stop", "delete"], + "x-enum-varnames": [ + "WorkspaceTransitionStart", + "WorkspaceTransitionStop", + "WorkspaceTransitionDelete" + ] + }, + "codersdk.WorkspacesResponse": { + "type": "object", + "properties": { + "count": { + "type": "integer" + }, + "workspaces": { + "type": "array", + "items": { + "$ref": "#/definitions/codersdk.Workspace" + } + } + } + }, + "database.ParameterDestinationScheme": { + "type": "string", + "enum": ["none", "environment_variable", "provisioner_variable"], + "x-enum-varnames": [ + "ParameterDestinationSchemeNone", + "ParameterDestinationSchemeEnvironmentVariable", + "ParameterDestinationSchemeProvisionerVariable" + ] + }, + "database.ParameterScope": { + "type": "string", + "enum": ["template", "import_job", "workspace"], + "x-enum-varnames": [ + "ParameterScopeTemplate", + "ParameterScopeImportJob", + "ParameterScopeWorkspace" + ] + }, + "database.ParameterSourceScheme": { + "type": "string", + "enum": ["none", "data"], + "x-enum-varnames": [ + "ParameterSourceSchemeNone", + "ParameterSourceSchemeData" + ] + }, + "parameter.ComputedValue": { + "type": "object", + "properties": { + "created_at": { + "type": "string" }, - "codersdk.WorkspaceConnectionLatencyMS": { - "type": "object", - "properties": { - "p50": { - "type": "number" - }, - "p95": { - "type": "number" - } - } + "default_source_value": { + "type": "boolean" }, - "codersdk.WorkspaceDeploymentStats": { - "type": "object", - "properties": { - "building": { - "type": "integer" - }, - "connection_latency_ms": { - "$ref": "#/definitions/codersdk.WorkspaceConnectionLatencyMS" - }, - "failed": { - "type": "integer" - }, - "pending": { - "type": "integer" - }, - "running": { - "type": "integer" - }, - "rx_bytes": { - "type": "integer" - }, - "stopped": { - "type": "integer" - }, - "tx_bytes": { - "type": "integer" - } - } - }, - "codersdk.WorkspaceQuota": { - "type": "object", - "properties": { - "budget": { - "type": "integer" - }, - "credits_consumed": { - "type": "integer" - } - } + "destination_scheme": { + "$ref": "#/definitions/database.ParameterDestinationScheme" }, - "codersdk.WorkspaceResource": { - "type": "object", - "properties": { - "agents": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceAgent" - } - }, - "created_at": { - "type": "string", - "format": "date-time" - }, - "daily_cost": { - "type": "integer" - }, - "hide": { - "type": "boolean" - }, - "icon": { - "type": "string" - }, - "id": { - "type": "string", - "format": "uuid" - }, - "job_id": { - "type": "string", - "format": "uuid" - }, - "metadata": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.WorkspaceResourceMetadata" - } - }, - "name": { - "type": "string" - }, - "type": { - "type": "string" - }, - "workspace_transition": { - "enum": [ - "start", - "stop", - "delete" - ], - "allOf": [ - { - "$ref": "#/definitions/codersdk.WorkspaceTransition" - } - ] - } - } - }, - "codersdk.WorkspaceResourceMetadata": { - "type": "object", - "properties": { - "key": { - "type": "string" - }, - "sensitive": { - "type": "boolean" - }, - "value": { - "type": "string" - } - } + "id": { + "type": "string" }, - "codersdk.WorkspaceStatus": { - "type": "string", - "enum": [ - "pending", - "starting", - "running", - "stopping", - "stopped", - "failed", - "canceling", - "canceled", - "deleting", - "deleted" - ], - "x-enum-varnames": [ - "WorkspaceStatusPending", - "WorkspaceStatusStarting", - "WorkspaceStatusRunning", - "WorkspaceStatusStopping", - "WorkspaceStatusStopped", - "WorkspaceStatusFailed", - "WorkspaceStatusCanceling", - "WorkspaceStatusCanceled", - "WorkspaceStatusDeleting", - "WorkspaceStatusDeleted" - ] - }, - "codersdk.WorkspaceTransition": { - "type": "string", - "enum": [ - "start", - "stop", - "delete" - ], - "x-enum-varnames": [ - "WorkspaceTransitionStart", - "WorkspaceTransitionStop", - "WorkspaceTransitionDelete" - ] + "name": { + "type": "string" }, - "codersdk.WorkspacesResponse": { - "type": "object", - "properties": { - "count": { - "type": "integer" - }, - "workspaces": { - "type": "array", - "items": { - "$ref": "#/definitions/codersdk.Workspace" - } - } - } + "schema_id": { + "type": "string" }, - "database.ParameterDestinationScheme": { - "type": "string", - "enum": [ - "none", - "environment_variable", - "provisioner_variable" - ], - "x-enum-varnames": [ - "ParameterDestinationSchemeNone", - "ParameterDestinationSchemeEnvironmentVariable", - "ParameterDestinationSchemeProvisionerVariable" - ] + "scope": { + "$ref": "#/definitions/database.ParameterScope" }, - "database.ParameterScope": { - "type": "string", - "enum": [ - "template", - "import_job", - "workspace" - ], - "x-enum-varnames": [ - "ParameterScopeTemplate", - "ParameterScopeImportJob", - "ParameterScopeWorkspace" - ] + "scope_id": { + "type": "string" }, - "database.ParameterSourceScheme": { - "type": "string", - "enum": [ - "none", - "data" - ], - "x-enum-varnames": [ - "ParameterSourceSchemeNone", - "ParameterSourceSchemeData" - ] + "source_scheme": { + "$ref": "#/definitions/database.ParameterSourceScheme" }, - "parameter.ComputedValue": { - "type": "object", - "properties": { - "created_at": { - "type": "string" - }, - "default_source_value": { - "type": "boolean" - }, - "destination_scheme": { - "$ref": "#/definitions/database.ParameterDestinationScheme" - }, - "id": { - "type": "string" - }, - "name": { - "type": "string" - }, - "schema_id": { - "type": "string" - }, - "scope": { - "$ref": "#/definitions/database.ParameterScope" - }, - "scope_id": { - "type": "string" - }, - "source_scheme": { - "$ref": "#/definitions/database.ParameterSourceScheme" - }, - "source_value": { - "type": "string" - }, - "updated_at": { - "type": "string" - } - } - }, - "sql.NullTime": { - "type": "object", - "properties": { - "time": { - "type": "string" - }, - "valid": { - "description": "Valid is true if Time is not NULL", - "type": "boolean" - } - } + "source_value": { + "type": "string" }, - "tailcfg.DERPMap": { - "type": "object", - "properties": { - "omitDefaultRegions": { - "description": "OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those\nspecified in this DERPMap. If there are none set outside of the defaults, this is a noop.", - "type": "boolean" - }, - "regions": { - "description": "Regions is the set of geographic regions running DERP node(s).\n\nIt's keyed by the DERPRegion.RegionID.\n\nThe numbers are not necessarily contiguous.", - "type": "object", - "additionalProperties": { - "$ref": "#/definitions/tailcfg.DERPRegion" - } - } - } - }, - "tailcfg.DERPNode": { - "type": "object", - "properties": { - "certName": { - "description": "CertName optionally specifies the expected TLS cert common\nname. If empty, HostName is used. If CertName is non-empty,\nHostName is only used for the TCP dial (if IPv4/IPv6 are\nnot present) + TLS ClientHello.", - "type": "string" - }, - "derpport": { - "description": "DERPPort optionally provides an alternate TLS port number\nfor the DERP HTTPS server.\n\nIf zero, 443 is used.", - "type": "integer" - }, - "forceHTTP": { - "description": "ForceHTTP is used by unit tests to force HTTP.\nIt should not be set by users.", - "type": "boolean" - }, - "hostName": { - "description": "HostName is the DERP node's hostname.\n\nIt is required but need not be unique; multiple nodes may\nhave the same HostName but vary in configuration otherwise.", - "type": "string" - }, - "insecureForTests": { - "description": "InsecureForTests is used by unit tests to disable TLS verification.\nIt should not be set by users.", - "type": "boolean" - }, - "ipv4": { - "description": "IPv4 optionally forces an IPv4 address to use, instead of using DNS.\nIf empty, A record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv4 address, IPv4 is not used; the\nconventional string to disable IPv4 (and not use DNS) is\n\"none\".", - "type": "string" - }, - "ipv6": { - "description": "IPv6 optionally forces an IPv6 address to use, instead of using DNS.\nIf empty, AAAA record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv6 address, IPv6 is not used; the\nconventional string to disable IPv6 (and not use DNS) is\n\"none\".", - "type": "string" - }, - "name": { - "description": "Name is a unique node name (across all regions).\nIt is not a host name.\nIt's typically of the form \"1b\", \"2a\", \"3b\", etc. (region\nID + suffix within that region)", - "type": "string" - }, - "regionID": { - "description": "RegionID is the RegionID of the DERPRegion that this node\nis running in.", - "type": "integer" - }, - "stunonly": { - "description": "STUNOnly marks a node as only a STUN server and not a DERP\nserver.", - "type": "boolean" - }, - "stunport": { - "description": "Port optionally specifies a STUN port to use.\nZero means 3478.\nTo disable STUN on this node, use -1.", - "type": "integer" - }, - "stuntestIP": { - "description": "STUNTestIP is used in tests to override the STUN server's IP.\nIf empty, it's assumed to be the same as the DERP server.", - "type": "string" - } - } - }, - "tailcfg.DERPRegion": { - "type": "object", - "properties": { - "avoid": { - "description": "Avoid is whether the client should avoid picking this as its home\nregion. The region should only be used if a peer is there.\nClients already using this region as their home should migrate\naway to a new region without Avoid set.", - "type": "boolean" - }, - "embeddedRelay": { - "description": "EmbeddedRelay is true when the region is bundled with the Coder\ncontrol plane.", - "type": "boolean" - }, - "nodes": { - "description": "Nodes are the DERP nodes running in this region, in\npriority order for the current client. Client TLS\nconnections should ideally only go to the first entry\n(falling back to the second if necessary). STUN packets\nshould go to the first 1 or 2.\n\nIf nodes within a region route packets amongst themselves,\nbut not to other regions. That said, each user/domain\nshould get a the same preferred node order, so if all nodes\nfor a user/network pick the first one (as they should, when\nthings are healthy), the inter-cluster routing is minimal\nto zero.", - "type": "array", - "items": { - "$ref": "#/definitions/tailcfg.DERPNode" - } - }, - "regionCode": { - "description": "RegionCode is a short name for the region. It's usually a popular\ncity or airport code in the region: \"nyc\", \"sf\", \"sin\",\n\"fra\", etc.", - "type": "string" - }, - "regionID": { - "description": "RegionID is a unique integer for a geographic region.\n\nIt corresponds to the legacy derpN.tailscale.com hostnames\nused by older clients. (Older clients will continue to resolve\nderpN.tailscale.com when contacting peers, rather than use\nthe server-provided DERPMap)\n\nRegionIDs must be non-zero, positive, and guaranteed to fit\nin a JavaScript number.\n\nRegionIDs in range 900-999 are reserved for end users to run their\nown DERP nodes.", - "type": "integer" - }, - "regionName": { - "description": "RegionName is a long English name for the region: \"New York City\",\n\"San Francisco\", \"Singapore\", \"Frankfurt\", etc.", - "type": "string" - } - } - }, - "url.Userinfo": { - "type": "object" - } - }, - "securityDefinitions": { - "CoderSessionToken": { - "type": "apiKey", - "name": "Coder-Session-Token", - "in": "header" + "updated_at": { + "type": "string" + } + } + }, + "sql.NullTime": { + "type": "object", + "properties": { + "time": { + "type": "string" + }, + "valid": { + "description": "Valid is true if Time is not NULL", + "type": "boolean" } + } + }, + "tailcfg.DERPMap": { + "type": "object", + "properties": { + "omitDefaultRegions": { + "description": "OmitDefaultRegions specifies to not use Tailscale's DERP servers, and only use those\nspecified in this DERPMap. If there are none set outside of the defaults, this is a noop.", + "type": "boolean" + }, + "regions": { + "description": "Regions is the set of geographic regions running DERP node(s).\n\nIt's keyed by the DERPRegion.RegionID.\n\nThe numbers are not necessarily contiguous.", + "type": "object", + "additionalProperties": { + "$ref": "#/definitions/tailcfg.DERPRegion" + } + } + } + }, + "tailcfg.DERPNode": { + "type": "object", + "properties": { + "certName": { + "description": "CertName optionally specifies the expected TLS cert common\nname. If empty, HostName is used. If CertName is non-empty,\nHostName is only used for the TCP dial (if IPv4/IPv6 are\nnot present) + TLS ClientHello.", + "type": "string" + }, + "derpport": { + "description": "DERPPort optionally provides an alternate TLS port number\nfor the DERP HTTPS server.\n\nIf zero, 443 is used.", + "type": "integer" + }, + "forceHTTP": { + "description": "ForceHTTP is used by unit tests to force HTTP.\nIt should not be set by users.", + "type": "boolean" + }, + "hostName": { + "description": "HostName is the DERP node's hostname.\n\nIt is required but need not be unique; multiple nodes may\nhave the same HostName but vary in configuration otherwise.", + "type": "string" + }, + "insecureForTests": { + "description": "InsecureForTests is used by unit tests to disable TLS verification.\nIt should not be set by users.", + "type": "boolean" + }, + "ipv4": { + "description": "IPv4 optionally forces an IPv4 address to use, instead of using DNS.\nIf empty, A record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv4 address, IPv4 is not used; the\nconventional string to disable IPv4 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "ipv6": { + "description": "IPv6 optionally forces an IPv6 address to use, instead of using DNS.\nIf empty, AAAA record(s) from DNS lookups of HostName are used.\nIf the string is not an IPv6 address, IPv6 is not used; the\nconventional string to disable IPv6 (and not use DNS) is\n\"none\".", + "type": "string" + }, + "name": { + "description": "Name is a unique node name (across all regions).\nIt is not a host name.\nIt's typically of the form \"1b\", \"2a\", \"3b\", etc. (region\nID + suffix within that region)", + "type": "string" + }, + "regionID": { + "description": "RegionID is the RegionID of the DERPRegion that this node\nis running in.", + "type": "integer" + }, + "stunonly": { + "description": "STUNOnly marks a node as only a STUN server and not a DERP\nserver.", + "type": "boolean" + }, + "stunport": { + "description": "Port optionally specifies a STUN port to use.\nZero means 3478.\nTo disable STUN on this node, use -1.", + "type": "integer" + }, + "stuntestIP": { + "description": "STUNTestIP is used in tests to override the STUN server's IP.\nIf empty, it's assumed to be the same as the DERP server.", + "type": "string" + } + } + }, + "tailcfg.DERPRegion": { + "type": "object", + "properties": { + "avoid": { + "description": "Avoid is whether the client should avoid picking this as its home\nregion. The region should only be used if a peer is there.\nClients already using this region as their home should migrate\naway to a new region without Avoid set.", + "type": "boolean" + }, + "embeddedRelay": { + "description": "EmbeddedRelay is true when the region is bundled with the Coder\ncontrol plane.", + "type": "boolean" + }, + "nodes": { + "description": "Nodes are the DERP nodes running in this region, in\npriority order for the current client. Client TLS\nconnections should ideally only go to the first entry\n(falling back to the second if necessary). STUN packets\nshould go to the first 1 or 2.\n\nIf nodes within a region route packets amongst themselves,\nbut not to other regions. That said, each user/domain\nshould get a the same preferred node order, so if all nodes\nfor a user/network pick the first one (as they should, when\nthings are healthy), the inter-cluster routing is minimal\nto zero.", + "type": "array", + "items": { + "$ref": "#/definitions/tailcfg.DERPNode" + } + }, + "regionCode": { + "description": "RegionCode is a short name for the region. It's usually a popular\ncity or airport code in the region: \"nyc\", \"sf\", \"sin\",\n\"fra\", etc.", + "type": "string" + }, + "regionID": { + "description": "RegionID is a unique integer for a geographic region.\n\nIt corresponds to the legacy derpN.tailscale.com hostnames\nused by older clients. (Older clients will continue to resolve\nderpN.tailscale.com when contacting peers, rather than use\nthe server-provided DERPMap)\n\nRegionIDs must be non-zero, positive, and guaranteed to fit\nin a JavaScript number.\n\nRegionIDs in range 900-999 are reserved for end users to run their\nown DERP nodes.", + "type": "integer" + }, + "regionName": { + "description": "RegionName is a long English name for the region: \"New York City\",\n\"San Francisco\", \"Singapore\", \"Frankfurt\", etc.", + "type": "string" + } + } + }, + "url.Userinfo": { + "type": "object" + } + }, + "securityDefinitions": { + "CoderSessionToken": { + "type": "apiKey", + "name": "Coder-Session-Token", + "in": "header" } -} \ No newline at end of file + } +} From 55b1308e382a1dcb68a3203838bf2d2373faf01a Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 10:46:40 -0500 Subject: [PATCH 20/29] remove experiment enum --- coderd/authorize.go | 22 ---------------------- codersdk/deployment.go | 4 ---- 2 files changed, 26 deletions(-) diff --git a/coderd/authorize.go b/coderd/authorize.go index 0681f38bf990c..ab1f3a39fd542 100644 --- a/coderd/authorize.go +++ b/coderd/authorize.go @@ -51,28 +51,6 @@ type HTTPAuthorizer struct { // return // } func (api *API) Authorize(r *http.Request, action rbac.Action, object rbac.Objecter) bool { - // The experiment does not replace ALL rbac checks, but does replace most. - // This statement aborts early on the checks that will be removed in the - // future when this experiment is default. - if api.Experiments.Enabled(codersdk.ExperimentAuthzQuerier) { - // Some resource types do not interact with the persistent layer and - // we need to keep these checks happening in the API layer. - switch object.RBACObject().Type { - case rbac.ResourceWorkspaceExecution.Type: - // This is not a db resource, always in API layer - case rbac.ResourceDeploymentValues.Type: - // For metric cache items like DAU, we do not hit the DB. - // Some db actions are in asserted in the authz layer. - case rbac.ResourceReplicas.Type: - // Replica rbac is checked for adding and removing replicas. - case rbac.ResourceProvisionerDaemon.Type: - // Provisioner rbac is checked for adding and removing provisioners. - case rbac.ResourceDebugInfo.Type: - // This is not a db resource, always in API layer. - default: - return true - } - } return api.HTTPAuth.Authorize(r, action, object) } diff --git a/codersdk/deployment.go b/codersdk/deployment.go index 8b822219cde96..dba09776a87b1 100644 --- a/codersdk/deployment.go +++ b/codersdk/deployment.go @@ -1516,10 +1516,6 @@ func (c *Client) BuildInfo(ctx context.Context) (BuildInfoResponse, error) { type Experiment string const ( - // ExperimentAuthzQuerier is an internal experiment that enables the ExperimentAuthzQuerier - // interface for all RBAC operations. NOT READY FOR PRODUCTION USE. - ExperimentAuthzQuerier Experiment = "authz_querier" - // ExperimentTemplateEditor is an internal experiment that enables the template editor // for all users. ExperimentTemplateEditor Experiment = "template_editor" From f7923df4a85ba40d332042715660288af7164ca4 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 15:49:54 +0000 Subject: [PATCH 21/29] Make gen --- coderd/apidoc/docs.go | 2 -- coderd/apidoc/swagger.json | 4 ++-- docs/api/general.md | 2 +- docs/api/schemas.md | 3 +-- site/src/api/typesGenerated.ts | 4 ++-- 5 files changed, 6 insertions(+), 9 deletions(-) diff --git a/coderd/apidoc/docs.go b/coderd/apidoc/docs.go index 74fb18f0dc42e..d3e5b48d58db0 100644 --- a/coderd/apidoc/docs.go +++ b/coderd/apidoc/docs.go @@ -6776,11 +6776,9 @@ const docTemplate = `{ "codersdk.Experiment": { "type": "string", "enum": [ - "authz_querier", "template_editor" ], "x-enum-varnames": [ - "ExperimentAuthzQuerier", "ExperimentTemplateEditor" ] }, diff --git a/coderd/apidoc/swagger.json b/coderd/apidoc/swagger.json index 074a6c4ab5ebc..913e02eb22c37 100644 --- a/coderd/apidoc/swagger.json +++ b/coderd/apidoc/swagger.json @@ -6063,8 +6063,8 @@ }, "codersdk.Experiment": { "type": "string", - "enum": ["authz_querier", "template_editor"], - "x-enum-varnames": ["ExperimentAuthzQuerier", "ExperimentTemplateEditor"] + "enum": ["template_editor"], + "x-enum-varnames": ["ExperimentTemplateEditor"] }, "codersdk.Feature": { "type": "object", diff --git a/docs/api/general.md b/docs/api/general.md index 23c7ba511fb07..0676876b4f277 100644 --- a/docs/api/general.md +++ b/docs/api/general.md @@ -507,7 +507,7 @@ curl -X GET http://coder-server:8080/api/v2/experiments \ > 200 Response ```json -["authz_querier"] +["template_editor"] ``` ### Responses diff --git a/docs/api/schemas.md b/docs/api/schemas.md index 6757825721bd0..441feb2201b44 100644 --- a/docs/api/schemas.md +++ b/docs/api/schemas.md @@ -2342,7 +2342,7 @@ CreateParameterRequest is a structure used to create a new parameter value for a ## codersdk.Experiment ```json -"authz_querier" +"template_editor" ``` ### Properties @@ -2351,7 +2351,6 @@ CreateParameterRequest is a structure used to create a new parameter value for a | Value | | ----------------- | -| `authz_querier` | | `template_editor` | ## codersdk.Feature diff --git a/site/src/api/typesGenerated.ts b/site/src/api/typesGenerated.ts index 1634b341b3162..4b31afb1f0ee0 100644 --- a/site/src/api/typesGenerated.ts +++ b/site/src/api/typesGenerated.ts @@ -1216,8 +1216,8 @@ export const Entitlements: Entitlement[] = [ ] // From codersdk/deployment.go -export type Experiment = "authz_querier" | "template_editor" -export const Experiments: Experiment[] = ["authz_querier", "template_editor"] +export type Experiment = "template_editor" +export const Experiments: Experiment[] = ["template_editor"] // From codersdk/deployment.go export type FeatureName = From 549a34d303d1dbbf3fd3ce9ca7568f6993605508 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 11:48:58 -0500 Subject: [PATCH 22/29] Linting --- coderd/coderdtest/authorize.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/coderdtest/authorize.go b/coderd/coderdtest/authorize.go index 678a88f60a99e..5e3918e7e6f02 100644 --- a/coderd/coderdtest/authorize.go +++ b/coderd/coderdtest/authorize.go @@ -104,7 +104,7 @@ func (a RBACAsserter) AssertInOrder(t *testing.T, action rbac.Action, objects .. // convertObjects converts the codersdk types to rbac.Object. Unfortunately // does not have type safety, and instead uses a t.Fatal to enforce types. -func (a RBACAsserter) convertObjects(t *testing.T, objs ...interface{}) []rbac.Object { +func (RBACAsserter) convertObjects(t *testing.T, objs ...interface{}) []rbac.Object { converted := make([]rbac.Object, 0, len(objs)) for _, obj := range objs { var robj rbac.Object From 2ae9eac013165ff786143fc5cf2c00eb56cd1931 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 12:14:52 -0500 Subject: [PATCH 23/29] Correct unit test --- enterprise/coderd/templates_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/enterprise/coderd/templates_test.go b/enterprise/coderd/templates_test.go index 7c58bd9527514..bf4e15214e63d 100644 --- a/enterprise/coderd/templates_test.go +++ b/enterprise/coderd/templates_test.go @@ -786,7 +786,7 @@ func TestUpdateTemplateACL(t *testing.T) { err = client2.UpdateTemplateACL(ctx, template.ID, req) require.Error(t, err) cerr, _ := codersdk.AsError(err) - require.Equal(t, http.StatusNotFound, cerr.StatusCode()) + require.Equal(t, http.StatusInternalServerError, cerr.StatusCode()) }) t.Run("RegularUserWithAdminCanUpdate", func(t *testing.T) { From 899cc690b23df2c409e6d257349ddc9624299247 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 15:27:47 -0500 Subject: [PATCH 24/29] Override a copy of the error --- coderd/database/dbauthz/dbauthz.go | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 2d177ef6fb79c..635099a82b629 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -50,8 +50,9 @@ func logNotAuthorizedError(ctx context.Context, logger slog.Logger, err error) e // // NotAuthorizedError is == to sql.ErrNoRows, which is not correct // if it's actually a canceled context. - internalError.SetInternal(context.Canceled) - return internalError + contextError := *internalError + contextError.SetInternal(context.Canceled) + return &contextError } logger.Debug(ctx, "unauthorized", slog.F("internal", internalError.Internal()), From 4fcc69ec2119295ae2d75adff2f7ecf435dd949a Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 16:02:25 -0500 Subject: [PATCH 25/29] have nicer status codes --- coderd/database/dbauthz/dbauthz.go | 7 +++++++ coderd/database/dbauthz/dbauthz_test.go | 5 +++++ coderd/users.go | 14 ++++++++++++++ coderd/users_test.go | 2 +- 4 files changed, 27 insertions(+), 1 deletion(-) diff --git a/coderd/database/dbauthz/dbauthz.go b/coderd/database/dbauthz/dbauthz.go index 635099a82b629..f82e703d86070 100644 --- a/coderd/database/dbauthz/dbauthz.go +++ b/coderd/database/dbauthz/dbauthz.go @@ -38,6 +38,13 @@ func (NotAuthorizedError) Unwrap() error { return sql.ErrNoRows } +func IsNotAuthorizedError(err error) bool { + if err == nil { + return false + } + return xerrors.As(err, &NotAuthorizedError{}) +} + func logNotAuthorizedError(ctx context.Context, logger slog.Logger, err error) error { // Only log the errors if it is an UnauthorizedError error. internalError := new(rbac.UnauthorizedError) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index ab4da817599db..1d6861449b976 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -21,6 +21,10 @@ import ( func TestAsNoActor(t *testing.T) { t.Parallel() + t.Run("NoError", func(t *testing.T) { + require.False(t, dbauthz.IsNotAuthorizedError(nil), "no error") + }) + t.Run("AsRemoveActor", func(t *testing.T) { t.Parallel() _, ok := dbauthz.ActorFromContext(context.Background()) @@ -80,6 +84,7 @@ func TestInTX(t *testing.T) { }, nil) require.Error(t, err, "must error") require.ErrorAs(t, err, &dbauthz.NotAuthorizedError{}, "must be an authorized error") + require.True(t, dbauthz.IsNotAuthorizedError(err), "must be an authorized error") } // TestNew should not double wrap a querier. diff --git a/coderd/users.go b/coderd/users.go index 26b3f557c5d9f..c39b33b931f9b 100644 --- a/coderd/users.go +++ b/coderd/users.go @@ -344,6 +344,12 @@ func (api *API) postUser(rw http.ResponseWriter, r *http.Request) { CreateUserRequest: req, LoginType: database.LoginTypePassword, }) + if dbauthz.IsNotAuthorizedError(err) { + httpapi.Write(ctx, rw, http.StatusForbidden, codersdk.Response{ + Message: "You are not authorized to create users.", + }) + return + } if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ Message: "Internal error creating user.", @@ -412,6 +418,10 @@ func (api *API) deleteUser(rw http.ResponseWriter, r *http.Request) { ID: user.ID, Deleted: true, }) + if dbauthz.IsNotAuthorizedError(err) { + httpapi.Forbidden(rw) + return + } if err != nil { httpapi.Write(ctx, rw, http.StatusInternalServerError, codersdk.Response{ Message: "Internal error deleting user.", @@ -825,6 +835,10 @@ func (api *API) putUserRoles(rw http.ResponseWriter, r *http.Request) { GrantedRoles: params.Roles, ID: user.ID, }) + if dbauthz.IsNotAuthorizedError(err) { + httpapi.Forbidden(rw) + return + } if err != nil { httpapi.Write(ctx, rw, http.StatusBadRequest, codersdk.Response{ Message: err.Error(), diff --git a/coderd/users_test.go b/coderd/users_test.go index 7f8283cdf018f..7aa0e6e8f848c 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -475,7 +475,7 @@ func TestPostUsers(t *testing.T) { }) var apiErr *codersdk.Error require.ErrorAs(t, err, &apiErr) - require.Equal(t, http.StatusForbidden, apiErr.StatusCode()) + require.Equal(t, http.StatusNotFound, apiErr.StatusCode()) }) t.Run("Create", func(t *testing.T) { From 4ab765f760cb8adbf0cb750e29cb17619ec80b3a Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 16:30:33 -0500 Subject: [PATCH 26/29] Test be parallel --- coderd/database/dbauthz/dbauthz_test.go | 1 + 1 file changed, 1 insertion(+) diff --git a/coderd/database/dbauthz/dbauthz_test.go b/coderd/database/dbauthz/dbauthz_test.go index 1d6861449b976..3fa5d3cdf1c5b 100644 --- a/coderd/database/dbauthz/dbauthz_test.go +++ b/coderd/database/dbauthz/dbauthz_test.go @@ -22,6 +22,7 @@ func TestAsNoActor(t *testing.T) { t.Parallel() t.Run("NoError", func(t *testing.T) { + t.Parallel() require.False(t, dbauthz.IsNotAuthorizedError(nil), "no error") }) From 9b69f3964da177693f921ea2008a8113f7952c6f Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 17:13:59 -0500 Subject: [PATCH 27/29] This test takes way too long --- coderd/users_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/coderd/users_test.go b/coderd/users_test.go index 7aa0e6e8f848c..4163d14c3354e 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -1497,7 +1497,7 @@ func TestPaginatedUsers(t *testing.T) { coderdtest.CreateFirstUser(t, client) // This test takes longer than a long time. - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*2) + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*4) t.Cleanup(cancel) me, err := client.User(ctx, codersdk.Me) From 974d915c3a374036aa6b4371cf72bcb65ca4c820 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 17:14:46 -0500 Subject: [PATCH 28/29] Paginated users was taking too long --- coderd/users_test.go | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/coderd/users_test.go b/coderd/users_test.go index 4163d14c3354e..22360744e4d79 100644 --- a/coderd/users_test.go +++ b/coderd/users_test.go @@ -1504,8 +1504,8 @@ func TestPaginatedUsers(t *testing.T) { require.NoError(t, err) orgID := me.OrganizationIDs[0] - // When 100 users exist - total := 100 + // When 50 users exist + total := 50 allUsers := make([]codersdk.User, total+1) // +1 forme allUsers[0] = me specialUsers := make([]codersdk.User, total/2) From 0934326660fb6d9d20c02f00c9772c6d6f78d700 Mon Sep 17 00:00:00 2001 From: Steven Masley Date: Mon, 20 Mar 2023 17:43:58 -0500 Subject: [PATCH 29/29] Subtest context is shared :( --- enterprise/coderd/templates_test.go | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/enterprise/coderd/templates_test.go b/enterprise/coderd/templates_test.go index bf4e15214e63d..65989da54383f 100644 --- a/enterprise/coderd/templates_test.go +++ b/enterprise/coderd/templates_test.go @@ -984,7 +984,9 @@ func TestUpdateTemplateACL(t *testing.T) { //nolint:tparallel func TestTemplateAccess(t *testing.T) { t.Parallel() - ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong) + // TODO: This context is for all the subtests. Each subtest should have its + // own context. + ctx, cancel := context.WithTimeout(context.Background(), testutil.WaitLong*3) t.Cleanup(cancel) ownerClient := coderdenttest.New(t, nil)