@opensoha/contracts 0.1.11 → 0.1.12

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.11",
2
+ "version": "0.1.12",
3
3
  "schemas": {
4
4
  "plugins/plugin-manifest.schema.json": {
5
5
  "rootRequired": ["id", "name", "publisher", "type", "version"],
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "0.1.11",
2
+ "version": "0.1.12",
3
3
  "generatedFrom": "openapi/soha-api.yaml",
4
4
  "entries": [
5
5
  {
@@ -0,0 +1,9 @@
1
+ {
2
+ "data": {
3
+ "hostId": "runtime-host-01",
4
+ "operationId": "host-sync-01",
5
+ "agentId": "docker-agent-01",
6
+ "agentBearerToken": "agent-secret-012345678901234567890",
7
+ "issuedAt": "2026-08-14T10:15:00Z"
8
+ }
9
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "data": {
3
+ "hostId": "runtime-host-01",
4
+ "operationId": "host-sync-01",
5
+ "agentId": "docker-agent-01",
6
+ "agentBearerToken": "agent-secret-012345678901234567890",
7
+ "runtimeBearerToken": "runtime-secret-012345678901234567",
8
+ "issuedAt": "2026-08-14T10:15:00Z"
9
+ }
10
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "agentId": "docker-agent-01",
3
+ "enrollmentToken": "too-short"
4
+ }
@@ -0,0 +1,4 @@
1
+ {
2
+ "agentId": "docker-agent-01",
3
+ "enrollmentToken": "enrollment-secret-0123456789012345"
4
+ }
@@ -14,7 +14,7 @@ import (
14
14
  "time"
15
15
  )
16
16
 
17
- const defaultUserAgent = "opensoha-contracts/0.1.11"
17
+ const defaultUserAgent = "opensoha-contracts/0.1.12"
18
18
 
19
19
  type Client struct {
20
20
  BaseURL string
@@ -404,6 +404,15 @@ func (c *Client) ClaimDockerOperation(ctx context.Context, req DockerOperationCl
404
404
  return out.Data, nil
405
405
  }
406
406
 
407
+ func (c *Client) ExchangeDockerHostAgentEnrollment(ctx context.Context, operationID string, req DockerHostAgentEnrollmentRequest) (DockerHostAgentCredentials, error) {
408
+ var out DockerHostAgentCredentialsEnvelope
409
+ path := "/docker/agent-installations/" + url.PathEscape(strings.TrimSpace(operationID)) + "/enroll"
410
+ if err := c.doJSON(ctx, http.MethodPost, path, false, req, &out); err != nil {
411
+ return DockerHostAgentCredentials{}, err
412
+ }
413
+ return out.Data, nil
414
+ }
415
+
407
416
  func (c *Client) GetDockerOperationRunnerStatus(ctx context.Context, operationID string) (DockerOperation, error) {
408
417
  var out DockerOperationEnvelope
409
418
  path := "/docker/operations/" + url.PathEscape(strings.TrimSpace(operationID)) + "/runner-status"
@@ -143,6 +143,35 @@ func TestRunnerClaimClientsAcceptNoContent(t *testing.T) {
143
143
  }
144
144
  }
145
145
 
146
+ func TestExchangeDockerHostAgentEnrollmentIsPublicAndReturnsCredentials(t *testing.T) {
147
+ issuedAt := time.Now().UTC().Truncate(time.Second)
148
+ client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
149
+ assertPublicRequest(t, r, http.MethodPost, "/api/v1/docker/agent-installations/operation-1/enroll")
150
+ request := decodeJSONRequestBody[DockerHostAgentEnrollmentRequest](t, r)
151
+ if request.AgentID != "host-1" || request.EnrollmentToken != "enrollment-secret-0123456789012345" {
152
+ t.Fatalf("enrollment request = %#v", request)
153
+ }
154
+ w.Header().Set("Cache-Control", "no-store")
155
+ w.WriteHeader(http.StatusCreated)
156
+ writeJSON(t, w, map[string]any{"data": map[string]any{
157
+ "hostId": "host-1", "operationId": "operation-1", "agentId": "host-1",
158
+ "agentBearerToken": "agent-secret-012345678901234567890",
159
+ "runtimeBearerToken": "runtime-secret-012345678901234567",
160
+ "issuedAt": issuedAt,
161
+ }})
162
+ })
163
+
164
+ credentials, err := client.ExchangeDockerHostAgentEnrollment(context.Background(), "operation-1", DockerHostAgentEnrollmentRequest{
165
+ AgentID: "host-1", EnrollmentToken: "enrollment-secret-0123456789012345",
166
+ })
167
+ if err != nil {
168
+ t.Fatalf("exchange enrollment: %v", err)
169
+ }
170
+ if credentials.HostID != "host-1" || credentials.OperationID != "operation-1" || credentials.RuntimeBearerToken == "" || credentials.AgentBearerToken == "" {
171
+ t.Fatalf("credentials = %#v", credentials)
172
+ }
173
+ }
174
+
146
175
  func TestRedeemSecretLeaseSendsRunnerBindingHeaders(t *testing.T) {
147
176
  client := newTestClient(t, func(w http.ResponseWriter, r *http.Request) {
148
177
  assertCommonRequest(t, r, http.MethodPost, "/api/v1/runner/secret-leases/lease%2Fone/redeem")
@@ -9758,6 +9758,32 @@ type DockerGitBuildInput struct {
9758
9758
  RepositoryURL string `json:"repositoryUrl"`
9759
9759
  }
9760
9760
 
9761
+ // DockerHostAgentCredentials defines model for DockerHostAgentCredentials.
9762
+ type DockerHostAgentCredentials struct {
9763
+ // AgentBearerToken Credential for the Agent's local HTTP API, returned only by the successful enrollment response.
9764
+ AgentBearerToken string `json:"agentBearerToken"`
9765
+ AgentID string `json:"agentId"`
9766
+ HostID string `json:"hostId"`
9767
+ IssuedAt time.Time `json:"issuedAt"`
9768
+ OperationID string `json:"operationId"`
9769
+
9770
+ // RuntimeBearerToken Revocable credential restricted to Docker operations for this host.
9771
+ RuntimeBearerToken string `json:"runtimeBearerToken"`
9772
+ }
9773
+
9774
+ // DockerHostAgentCredentialsEnvelope defines model for DockerHostAgentCredentialsEnvelope.
9775
+ type DockerHostAgentCredentialsEnvelope struct {
9776
+ Data DockerHostAgentCredentials `json:"data"`
9777
+ }
9778
+
9779
+ // DockerHostAgentEnrollmentRequest defines model for DockerHostAgentEnrollmentRequest.
9780
+ type DockerHostAgentEnrollmentRequest struct {
9781
+ AgentID string `json:"agentId"`
9782
+
9783
+ // EnrollmentToken Short-lived one-time secret delivered only inside the installer.
9784
+ EnrollmentToken string `json:"enrollmentToken"`
9785
+ }
9786
+
9761
9787
  // DockerHostAgentInstallation defines model for DockerHostAgentInstallation.
9762
9788
  type DockerHostAgentInstallation struct {
9763
9789
  Command string `json:"command"`
@@ -21526,6 +21552,9 @@ type TriggerManifestSourceWebhookJSONRequestBody = ManifestSyncWebhookInput
21526
21552
  // CreateDeliveryPlanJSONRequestBody defines body for CreateDeliveryPlan for application/json ContentType.
21527
21553
  type CreateDeliveryPlanJSONRequestBody = DeliveryPlanInput
21528
21554
 
21555
+ // ExchangeDockerHostAgentEnrollmentJSONRequestBody defines body for ExchangeDockerHostAgentEnrollment for application/json ContentType.
21556
+ type ExchangeDockerHostAgentEnrollmentJSONRequestBody = DockerHostAgentEnrollmentRequest
21557
+
21529
21558
  // StartDockerContainerJSONRequestBody defines body for StartDockerContainer for application/json ContentType.
21530
21559
  type StartDockerContainerJSONRequestBody = DockerContainerStartInput
21531
21560
 
@@ -2065,6 +2065,22 @@ export interface paths {
2065
2065
  patch?: never;
2066
2066
  trace?: never;
2067
2067
  };
2068
+ "/docker/agent-installations/{operationID}/enroll": {
2069
+ parameters: {
2070
+ query?: never;
2071
+ header?: never;
2072
+ path?: never;
2073
+ cookie?: never;
2074
+ };
2075
+ get?: never;
2076
+ put?: never;
2077
+ post: operations["exchangeDockerHostAgentEnrollment"];
2078
+ delete?: never;
2079
+ options?: never;
2080
+ head?: never;
2081
+ patch?: never;
2082
+ trace?: never;
2083
+ };
2068
2084
  "/docker/hosts/quick-create/plan": {
2069
2085
  parameters: {
2070
2086
  query?: never;
@@ -15240,6 +15256,34 @@ export interface components {
15240
15256
  DockerHostAgentInstallationEnvelope: {
15241
15257
  data: components["schemas"]["DockerHostAgentInstallation"];
15242
15258
  };
15259
+ DockerHostAgentEnrollmentRequest: {
15260
+ agentId: string;
15261
+ /**
15262
+ * Format: password
15263
+ * @description Short-lived one-time secret delivered only inside the installer.
15264
+ */
15265
+ enrollmentToken: string;
15266
+ };
15267
+ DockerHostAgentCredentials: {
15268
+ hostId: string;
15269
+ operationId: string;
15270
+ agentId: string;
15271
+ /**
15272
+ * Format: password
15273
+ * @description Credential for the Agent's local HTTP API, returned only by the successful enrollment response.
15274
+ */
15275
+ agentBearerToken: string;
15276
+ /**
15277
+ * Format: password
15278
+ * @description Revocable credential restricted to Docker operations for this host.
15279
+ */
15280
+ runtimeBearerToken: string;
15281
+ /** Format: date-time */
15282
+ issuedAt: string;
15283
+ };
15284
+ DockerHostAgentCredentialsEnvelope: {
15285
+ data: components["schemas"]["DockerHostAgentCredentials"];
15286
+ };
15243
15287
  /** @enum {string} */
15244
15288
  ObservabilityProviderSignal: "logs" | "metrics" | "traces" | "profiles";
15245
15289
  /** @enum {string} */
@@ -19162,6 +19206,9 @@ export type AgentInstallation = components['schemas']['AgentInstallation'];
19162
19206
  export type AgentInstallationEnvelope = components['schemas']['AgentInstallationEnvelope'];
19163
19207
  export type DockerHostAgentInstallation = components['schemas']['DockerHostAgentInstallation'];
19164
19208
  export type DockerHostAgentInstallationEnvelope = components['schemas']['DockerHostAgentInstallationEnvelope'];
19209
+ export type DockerHostAgentEnrollmentRequest = components['schemas']['DockerHostAgentEnrollmentRequest'];
19210
+ export type DockerHostAgentCredentials = components['schemas']['DockerHostAgentCredentials'];
19211
+ export type DockerHostAgentCredentialsEnvelope = components['schemas']['DockerHostAgentCredentialsEnvelope'];
19165
19212
  export type ObservabilityProviderSignal = components['schemas']['ObservabilityProviderSignal'];
19166
19213
  export type ObservabilityProviderRuntimeMode = components['schemas']['ObservabilityProviderRuntimeMode'];
19167
19214
  export type ObservabilityProviderStatus = components['schemas']['ObservabilityProviderStatus'];
@@ -23776,6 +23823,38 @@ export interface operations {
23776
23823
  410: components["responses"]["Error"];
23777
23824
  };
23778
23825
  };
23826
+ exchangeDockerHostAgentEnrollment: {
23827
+ parameters: {
23828
+ query?: never;
23829
+ header?: never;
23830
+ path: {
23831
+ operationID: components["parameters"]["OperationID"];
23832
+ };
23833
+ cookie?: never;
23834
+ };
23835
+ requestBody: {
23836
+ content: {
23837
+ "application/json": components["schemas"]["DockerHostAgentEnrollmentRequest"];
23838
+ };
23839
+ };
23840
+ responses: {
23841
+ /** @description One-time host-bound Agent and control-plane credentials. The enrollment token is atomically consumed by a successful response. */
23842
+ 201: {
23843
+ headers: {
23844
+ /** @description Prevents credential responses from being cached. */
23845
+ "Cache-Control"?: "no-store";
23846
+ [name: string]: unknown;
23847
+ };
23848
+ content: {
23849
+ "application/json": components["schemas"]["DockerHostAgentCredentialsEnvelope"];
23850
+ };
23851
+ };
23852
+ 400: components["responses"]["Error"];
23853
+ 404: components["responses"]["Error"];
23854
+ 409: components["responses"]["Error"];
23855
+ 410: components["responses"]["Error"];
23856
+ };
23857
+ };
23779
23858
  planDockerHostQuickCreate: {
23780
23859
  parameters: {
23781
23860
  query?: never;
@@ -10063,6 +10063,85 @@
10063
10063
  ],
10064
10064
  "type": "object"
10065
10065
  },
10066
+ "DockerHostAgentCredentials": {
10067
+ "additionalProperties": false,
10068
+ "properties": {
10069
+ "agentBearerToken": {
10070
+ "description": "Credential for the Agent's local HTTP API, returned only by the successful enrollment response.",
10071
+ "format": "password",
10072
+ "maxLength": 512,
10073
+ "minLength": 32,
10074
+ "type": "string"
10075
+ },
10076
+ "agentId": {
10077
+ "maxLength": 200,
10078
+ "minLength": 1,
10079
+ "type": "string"
10080
+ },
10081
+ "hostId": {
10082
+ "minLength": 1,
10083
+ "type": "string"
10084
+ },
10085
+ "issuedAt": {
10086
+ "format": "date-time",
10087
+ "type": "string"
10088
+ },
10089
+ "operationId": {
10090
+ "minLength": 1,
10091
+ "type": "string"
10092
+ },
10093
+ "runtimeBearerToken": {
10094
+ "description": "Revocable credential restricted to Docker operations for this host.",
10095
+ "format": "password",
10096
+ "maxLength": 512,
10097
+ "minLength": 32,
10098
+ "type": "string"
10099
+ }
10100
+ },
10101
+ "required": [
10102
+ "hostId",
10103
+ "operationId",
10104
+ "agentId",
10105
+ "agentBearerToken",
10106
+ "runtimeBearerToken",
10107
+ "issuedAt"
10108
+ ],
10109
+ "type": "object"
10110
+ },
10111
+ "DockerHostAgentCredentialsEnvelope": {
10112
+ "additionalProperties": false,
10113
+ "properties": {
10114
+ "data": {
10115
+ "$ref": "#/components/schemas/DockerHostAgentCredentials"
10116
+ }
10117
+ },
10118
+ "required": [
10119
+ "data"
10120
+ ],
10121
+ "type": "object"
10122
+ },
10123
+ "DockerHostAgentEnrollmentRequest": {
10124
+ "additionalProperties": false,
10125
+ "properties": {
10126
+ "agentId": {
10127
+ "maxLength": 200,
10128
+ "minLength": 1,
10129
+ "type": "string"
10130
+ },
10131
+ "enrollmentToken": {
10132
+ "description": "Short-lived one-time secret delivered only inside the installer.",
10133
+ "format": "password",
10134
+ "maxLength": 512,
10135
+ "minLength": 32,
10136
+ "type": "string"
10137
+ }
10138
+ },
10139
+ "required": [
10140
+ "agentId",
10141
+ "enrollmentToken"
10142
+ ],
10143
+ "type": "object"
10144
+ },
10066
10145
  "DockerHostAgentInstallation": {
10067
10146
  "additionalProperties": false,
10068
10147
  "properties": {
@@ -41073,7 +41152,7 @@
41073
41152
  "type": "http"
41074
41153
  },
41075
41154
  "runtimeBearerAuth": {
41076
- "description": "Runtime execution runner token.",
41155
+ "description": "Runtime execution runner token, including host-bound Docker Agent credentials.",
41077
41156
  "scheme": "bearer",
41078
41157
  "type": "http"
41079
41158
  },
@@ -41088,7 +41167,7 @@
41088
41167
  "info": {
41089
41168
  "description": "Public OpenSoha core API contract. This first contract focuses on stable cross-repository boundaries: auth, health, runner-facing control-plane callbacks, AI Gateway, and MCP capability discovery.\n",
41090
41169
  "title": "Soha API",
41091
- "version": "0.1.11"
41170
+ "version": "0.1.12"
41092
41171
  },
41093
41172
  "openapi": "3.1.0",
41094
41173
  "paths": {
@@ -57072,6 +57151,63 @@
57072
57151
  "x-soha-implementation-status": "implemented"
57073
57152
  }
57074
57153
  },
57154
+ "/docker/agent-installations/{operationID}/enroll": {
57155
+ "post": {
57156
+ "operationId": "exchangeDockerHostAgentEnrollment",
57157
+ "parameters": [
57158
+ {
57159
+ "$ref": "#/components/parameters/OperationID"
57160
+ }
57161
+ ],
57162
+ "requestBody": {
57163
+ "content": {
57164
+ "application/json": {
57165
+ "schema": {
57166
+ "$ref": "#/components/schemas/DockerHostAgentEnrollmentRequest"
57167
+ }
57168
+ }
57169
+ },
57170
+ "required": true
57171
+ },
57172
+ "responses": {
57173
+ "201": {
57174
+ "content": {
57175
+ "application/json": {
57176
+ "schema": {
57177
+ "$ref": "#/components/schemas/DockerHostAgentCredentialsEnvelope"
57178
+ }
57179
+ }
57180
+ },
57181
+ "description": "One-time host-bound Agent and control-plane credentials. The enrollment token is atomically consumed by a successful response.",
57182
+ "headers": {
57183
+ "Cache-Control": {
57184
+ "description": "Prevents credential responses from being cached.",
57185
+ "schema": {
57186
+ "const": "no-store",
57187
+ "type": "string"
57188
+ }
57189
+ }
57190
+ }
57191
+ },
57192
+ "400": {
57193
+ "$ref": "#/components/responses/Error"
57194
+ },
57195
+ "404": {
57196
+ "$ref": "#/components/responses/Error"
57197
+ },
57198
+ "409": {
57199
+ "$ref": "#/components/responses/Error"
57200
+ },
57201
+ "410": {
57202
+ "$ref": "#/components/responses/Error"
57203
+ }
57204
+ },
57205
+ "security": [],
57206
+ "tags": [
57207
+ "Runner"
57208
+ ]
57209
+ }
57210
+ },
57075
57211
  "/docker/containers/start": {
57076
57212
  "post": {
57077
57213
  "operationId": "startDockerContainer",
@@ -1,7 +1,7 @@
1
1
  openapi: 3.1.0
2
2
  info:
3
3
  title: Soha API
4
- version: 0.1.11
4
+ version: 0.1.12
5
5
  description: >
6
6
  Public OpenSoha core API contract. This first contract focuses on stable
7
7
  cross-repository boundaries: auth, health, runner-facing control-plane
@@ -3295,6 +3295,38 @@ paths:
3295
3295
  $ref: "#/components/responses/Error"
3296
3296
  "410":
3297
3297
  $ref: "#/components/responses/Error"
3298
+ /docker/agent-installations/{operationID}/enroll:
3299
+ post:
3300
+ tags: [Runner]
3301
+ operationId: exchangeDockerHostAgentEnrollment
3302
+ security: []
3303
+ parameters:
3304
+ - $ref: "#/components/parameters/OperationID"
3305
+ requestBody:
3306
+ required: true
3307
+ content:
3308
+ application/json:
3309
+ schema:
3310
+ $ref: "#/components/schemas/DockerHostAgentEnrollmentRequest"
3311
+ responses:
3312
+ "201":
3313
+ description: One-time host-bound Agent and control-plane credentials. The enrollment token is atomically consumed by a successful response.
3314
+ headers:
3315
+ Cache-Control:
3316
+ description: Prevents credential responses from being cached.
3317
+ schema: { type: string, const: no-store }
3318
+ content:
3319
+ application/json:
3320
+ schema:
3321
+ $ref: "#/components/schemas/DockerHostAgentCredentialsEnvelope"
3322
+ "400":
3323
+ $ref: "#/components/responses/Error"
3324
+ "404":
3325
+ $ref: "#/components/responses/Error"
3326
+ "409":
3327
+ $ref: "#/components/responses/Error"
3328
+ "410":
3329
+ $ref: "#/components/responses/Error"
3298
3330
  /docker/hosts/quick-create/plan:
3299
3331
  post:
3300
3332
  tags: [Docker]
@@ -11944,7 +11976,7 @@ components:
11944
11976
  runtimeBearerAuth:
11945
11977
  type: http
11946
11978
  scheme: bearer
11947
- description: Runtime execution runner token.
11979
+ description: Runtime execution runner token, including host-bound Docker Agent credentials.
11948
11980
  agentBearerAuth:
11949
11981
  type: http
11950
11982
  scheme: bearer
@@ -25915,6 +25947,58 @@ components:
25915
25947
  data:
25916
25948
  $ref: "#/components/schemas/DockerHostAgentInstallation"
25917
25949
  additionalProperties: false
25950
+ DockerHostAgentEnrollmentRequest:
25951
+ type: object
25952
+ required: [agentId, enrollmentToken]
25953
+ properties:
25954
+ agentId:
25955
+ type: string
25956
+ minLength: 1
25957
+ maxLength: 200
25958
+ enrollmentToken:
25959
+ type: string
25960
+ minLength: 32
25961
+ maxLength: 512
25962
+ format: password
25963
+ description: Short-lived one-time secret delivered only inside the installer.
25964
+ additionalProperties: false
25965
+ DockerHostAgentCredentials:
25966
+ type: object
25967
+ required: [hostId, operationId, agentId, agentBearerToken, runtimeBearerToken, issuedAt]
25968
+ properties:
25969
+ hostId:
25970
+ type: string
25971
+ minLength: 1
25972
+ operationId:
25973
+ type: string
25974
+ minLength: 1
25975
+ agentId:
25976
+ type: string
25977
+ minLength: 1
25978
+ maxLength: 200
25979
+ agentBearerToken:
25980
+ type: string
25981
+ minLength: 32
25982
+ maxLength: 512
25983
+ format: password
25984
+ description: Credential for the Agent's local HTTP API, returned only by the successful enrollment response.
25985
+ runtimeBearerToken:
25986
+ type: string
25987
+ minLength: 32
25988
+ maxLength: 512
25989
+ format: password
25990
+ description: Revocable credential restricted to Docker operations for this host.
25991
+ issuedAt:
25992
+ type: string
25993
+ format: date-time
25994
+ additionalProperties: false
25995
+ DockerHostAgentCredentialsEnvelope:
25996
+ type: object
25997
+ required: [data]
25998
+ properties:
25999
+ data:
26000
+ $ref: "#/components/schemas/DockerHostAgentCredentials"
26001
+ additionalProperties: false
25918
26002
  ObservabilityProviderSignal:
25919
26003
  type: string
25920
26004
  enum: [logs, metrics, traces, profiles]
@@ -5,9 +5,9 @@ package openapi
5
5
  import _ "embed"
6
6
 
7
7
  const (
8
- Version = "0.1.11"
9
- YAMLSHA256 = "84fc6e95a10bbbf20bc8b2adbda86d824bf664d1ca16c879c37cf1005ed47557"
10
- JSONSHA256 = "551abf1b2ab9a56f0b59de7d43d1d59c0145d88cf8a017e1c0a937441947fdff"
8
+ Version = "0.1.12"
9
+ YAMLSHA256 = "b9dbd5597000f9124790f0df8e9e7616e76f7d7e12df03b72490c3403da4eda5"
10
+ JSONSHA256 = "6f34774013b3e6c9dd0e2c9b3e9d929a68f8f8b659a5909dad64a77821ef24dd"
11
11
  )
12
12
 
13
13
  //go:embed soha-api.yaml
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@opensoha/contracts",
3
- "version": "0.1.11",
3
+ "version": "0.1.12",
4
4
  "private": false,
5
5
  "description": "Shared OpenSoha API, agent, MCP, skill, event, and auth contracts.",
6
6
  "license": "Apache-2.0",