feat: enforce explicit Subject permissions and delegated Worker grants

This commit is contained in:
2026-10-20 06:22:58 +09:00
parent a774925dec
commit b135fa5e99
52 changed files with 7422 additions and 100 deletions
+462 -1
View File
@@ -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",