feat: operator trust root: passkey-signed operator set, signed join codes, nodes verify and pin the chain at enrollment [CI SKIP]

This commit is contained in:
justme committed 2026-10-07 23:19:59 +08:00
1 parent 321cacac32
commit fc2bbdcc6d
35 files changed
+1374 -40

No files matched your search

+326
View File
@@ -3887,6 +3887,190 @@
"x-moshiro-capability": "audit.read"
}
},
"/api/admin/trust": {
"get": {
"tags": [
"admin-trust"
],
"summary": "The operator trust root: genesis fingerprint, version, whether it matches the registered passkeys, and the next version to sign",
"operationId": "trust_get",
"responses": {
"200": {
"description": "OK",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrustStateDto"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
}
},
"x-moshiro-capability": "fleet.read"
},
"post": {
"tags": [
"admin-trust"
],
"summary": "Store the next operator set, signed with a passkey (the first one sets the genesis and needs a credential window)",
"operationId": "trust_commit",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/SignedStatementDto"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/TrustStateDto"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"409": {
"description": "Conflict",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
}
},
"x-moshiro-capability": "accounts.manage"
}
},
"/api/admin/join-tokens/signed": {
"post": {
"tags": [
"admin-trust"
],
"summary": "Create a join code from a grant the operator signed with a passkey; the browser derives the code from a seed the panel never sees",
"operationId": "join_tokens_create_signed",
"requestBody": {
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/CreateSignedJoinTokenRequest"
}
}
},
"required": true
},
"responses": {
"201": {
"description": "Created",
"content": {
"application/json": {
"schema": {
"$ref": "#/components/schemas/JoinTokenDto"
}
}
}
},
"400": {
"description": "Bad Request",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"401": {
"description": "Unauthorized",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"403": {
"description": "Forbidden",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
},
"409": {
"description": "Conflict",
"content": {
"application/problem+json": {
"schema": {
"$ref": "#/components/schemas/ProblemDto"
}
}
}
}
},
"x-moshiro-capability": "fleet.enroll"
}
},
"/api/admin/api-tokens": {
"get": {
"tags": [
@@ -4959,6 +5143,20 @@
}
}
}
},
"/api/agent/v1/enroll/trust": {
"post": {
"tags": [
"agent"
],
"summary": "The operator set chain and the grant of a join token, for the node to verify before it enrolls",
"operationId": "fleet_enroll_trust",
"responses": {
"200": {
"description": "OK"
}
}
}
}
},
"components": {
@@ -5820,6 +6018,41 @@
}
}
},
"CreateSignedJoinTokenRequest": {
"required": [
"grant",
"note",
"labels",
"auto_approve"
],
"type": "object",
"properties": {
"grant": {
"$ref": "#/components/schemas/SignedStatementDto"
},
"note": {
"type": [
"null",
"string"
]
},
"labels": {
"type": [
"null",
"array"
],
"items": {
"type": "string"
}
},
"auto_approve": {
"type": [
"null",
"boolean"
]
}
}
},
"CreateTaskRequest": {
"required": [
"scope",
@@ -6681,6 +6914,10 @@
"null",
"string"
]
},
"signed": {
"type": "boolean",
"default": false
}
}
},
@@ -8733,6 +8970,26 @@
}
}
},
"SignedStatementDto": {
"type": "object",
"properties": {
"statement": {
"type": "string"
},
"credential_id": {
"type": "string"
},
"authenticator_data": {
"type": "string"
},
"client_data_json": {
"type": "string"
},
"signature": {
"type": "string"
}
}
},
"StartTestRequestDto": {
"required": [
"plan",
@@ -9084,6 +9341,72 @@
}
}
},
"TrustProposalDto": {
"required": [
"statement",
"version",
"challenge"
],
"type": "object",
"properties": {
"statement": {
"type": "string"
},
"version": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"integer",
"string"
],
"format": "int32"
},
"challenge": {
"type": "string"
}
}
},
"TrustStateDto": {
"required": [
"initialized",
"genesis",
"version",
"in_sync",
"proposal"
],
"type": "object",
"properties": {
"initialized": {
"type": "boolean"
},
"genesis": {
"type": [
"null",
"string"
]
},
"version": {
"pattern": "^-?(?:0|[1-9]\\d*)$",
"type": [
"integer",
"string"
],
"format": "int32"
},
"in_sync": {
"type": "boolean"
},
"proposal": {
"oneOf": [
{
"type": "null"
},
{
"$ref": "#/components/schemas/TrustProposalDto"
}
]
}
}
},
"UserDto": {
"required": [
"id",
@@ -9142,6 +9465,9 @@
{
"name": "admin-audit"
},
{
"name": "admin-trust"
},
{
"name": "admin-api-tokens"
},