feat: enforce explicit Subject permissions and delegated Worker grants
This commit is contained in:
+462
-1
@@ -1589,6 +1589,18 @@
|
||||
"display_name": {
|
||||
"type": "string"
|
||||
},
|
||||
"execution_grant": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/WorkerDelegationRequest"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
],
|
||||
"default": null,
|
||||
"description": "Requested least-authority child permissions. Host derives the origin; this\ninput cannot assert Subject identity or create a body/singleton attachment."
|
||||
},
|
||||
"feature_connections": {
|
||||
"$ref": "#/components/schemas/WorkspaceWorkerFeatureConnectionsRequest",
|
||||
"description": "Explicit product Feature connections. Backend validation turns these into\ntrusted host attachments; Runtime and Profile inputs cannot self-attest them."
|
||||
@@ -6830,6 +6842,86 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"PermissionResource": {
|
||||
"oneOf": [
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"kind": {
|
||||
"const": "feature",
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"kind": {
|
||||
"const": "workspace",
|
||||
"type": "string"
|
||||
},
|
||||
"workspace_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"workspace_id"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"kind": {
|
||||
"const": "workdir",
|
||||
"type": "string"
|
||||
},
|
||||
"path": {
|
||||
"type": "string"
|
||||
},
|
||||
"recursive": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"working_directory_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"working_directory_id",
|
||||
"path",
|
||||
"recursive"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
{
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"kind": {
|
||||
"const": "worker",
|
||||
"type": "string"
|
||||
},
|
||||
"runtime_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"worker_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"kind",
|
||||
"runtime_id",
|
||||
"worker_id"
|
||||
],
|
||||
"type": "object"
|
||||
}
|
||||
]
|
||||
},
|
||||
"ProfileSettingsResponse": {
|
||||
"additionalProperties": false,
|
||||
"description": "Read-only Profile catalog projected from one active Workspace config tree.",
|
||||
@@ -9527,6 +9619,22 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"ScopedPermission": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"operation": {
|
||||
"type": "string"
|
||||
},
|
||||
"resource": {
|
||||
"$ref": "#/components/schemas/PermissionResource"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation",
|
||||
"resource"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"Segment": {
|
||||
"oneOf": [
|
||||
{
|
||||
@@ -10175,6 +10283,131 @@
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubjectPermissionInterruption": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"backend_command_sessions_closed": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"cancellation_accepted": {
|
||||
"type": "boolean"
|
||||
},
|
||||
"diagnostics": {
|
||||
"items": {
|
||||
"type": "string"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"runtime_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"worker_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"runtime_id",
|
||||
"worker_id",
|
||||
"cancellation_accepted",
|
||||
"backend_command_sessions_closed",
|
||||
"diagnostics"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubjectPermissions": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"change_id": {
|
||||
"type": "string"
|
||||
},
|
||||
"delegation": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ScopedPermission"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"execution": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ScopedPermission"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"change_id",
|
||||
"execution",
|
||||
"delegation"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubjectPermissionsMutationResponse": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"interruptions": {
|
||||
"description": "New operations are already fenced. These are cancellation requests and\nBackend command cleanup evidence, not proof that a Runtime turn stopped.",
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/SubjectPermissionInterruption"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"permissions": {
|
||||
"$ref": "#/components/schemas/SubjectPermissions"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"permissions",
|
||||
"interruptions"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubjectPermissionsResponse": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"anyOf": [
|
||||
{
|
||||
"$ref": "#/components/schemas/SubjectPermissions"
|
||||
},
|
||||
{
|
||||
"type": "null"
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"type": "object"
|
||||
},
|
||||
"SubjectPermissionsUpdate": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"delegation": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ScopedPermission"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"execution": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ScopedPermission"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"expected_change_id": {
|
||||
"type": [
|
||||
"string",
|
||||
"null"
|
||||
]
|
||||
},
|
||||
"operation_id": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"operation_id",
|
||||
"execution",
|
||||
"delegation"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"SubjektivMemoryChangeItem": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -14899,6 +15132,28 @@
|
||||
}
|
||||
]
|
||||
},
|
||||
"WorkerDelegationRequest": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
"permissions": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ScopedPermission"
|
||||
},
|
||||
"type": "array"
|
||||
},
|
||||
"redelegation": {
|
||||
"items": {
|
||||
"$ref": "#/components/schemas/ScopedPermission"
|
||||
},
|
||||
"type": "array"
|
||||
}
|
||||
},
|
||||
"required": [
|
||||
"permissions",
|
||||
"redelegation"
|
||||
],
|
||||
"type": "object"
|
||||
},
|
||||
"WorkerFileDeleteResponse": {
|
||||
"additionalProperties": false,
|
||||
"properties": {
|
||||
@@ -17844,7 +18099,7 @@
|
||||
"info": {
|
||||
"title": "Yoi Server API",
|
||||
"version": "0.1.0",
|
||||
"x-yoi-source-digest": "sha256:becabc09349e8011b1a5d96b0126c3bb50697ffa4e3b400b92ec1f79a966aafb"
|
||||
"x-yoi-source-digest": "sha256:e151963ec3fa9836f43bea7f0f4f17b4a18798b43c111c983c6a2e2ccfd61a01"
|
||||
},
|
||||
"openapi": "3.1.0",
|
||||
"paths": {
|
||||
@@ -35000,6 +35255,212 @@
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/w/{workspace_id}/subjektiv/subjects/{subject_id}/permissions": {
|
||||
"get": {
|
||||
"operationId": "subjektiv_subject_permissions_get",
|
||||
"parameters": [
|
||||
{
|
||||
"explode": false,
|
||||
"in": "path",
|
||||
"name": "workspace_id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/string"
|
||||
},
|
||||
"style": "simple"
|
||||
},
|
||||
{
|
||||
"explode": false,
|
||||
"in": "path",
|
||||
"name": "subject_id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/string"
|
||||
},
|
||||
"style": "simple"
|
||||
}
|
||||
],
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SubjectPermissionsResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Successful response"
|
||||
},
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"401": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"403": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"404": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"browserSession": []
|
||||
}
|
||||
]
|
||||
},
|
||||
"post": {
|
||||
"operationId": "subjektiv_subject_permissions_set",
|
||||
"parameters": [
|
||||
{
|
||||
"explode": false,
|
||||
"in": "path",
|
||||
"name": "workspace_id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/string"
|
||||
},
|
||||
"style": "simple"
|
||||
},
|
||||
{
|
||||
"explode": false,
|
||||
"in": "path",
|
||||
"name": "subject_id",
|
||||
"required": true,
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/string"
|
||||
},
|
||||
"style": "simple"
|
||||
}
|
||||
],
|
||||
"requestBody": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SubjectPermissionsUpdate"
|
||||
}
|
||||
}
|
||||
},
|
||||
"required": true
|
||||
},
|
||||
"responses": {
|
||||
"200": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/SubjectPermissionsMutationResponse"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Successful response"
|
||||
},
|
||||
"400": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"401": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"403": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"404": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"409": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
},
|
||||
"500": {
|
||||
"content": {
|
||||
"application/json": {
|
||||
"schema": {
|
||||
"$ref": "#/components/schemas/RepositoryApiError"
|
||||
}
|
||||
}
|
||||
},
|
||||
"description": "Error response"
|
||||
}
|
||||
},
|
||||
"security": [
|
||||
{
|
||||
"browserSession": []
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"/api/w/{workspace_id}/subjektiv/subjects/{subject_id}/retire": {
|
||||
"post": {
|
||||
"operationId": "subjektiv_subject_retire",
|
||||
|
||||
Reference in New Issue
Block a user