1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
{
"lexicon": 1,
"id": "com.publicdomainrelay.temp.cluster.getKubeconfig",
"defs": {
"main": {
"type": "procedure",
"description": "Return a kubeconfig for the named cluster of the calling account. Creates on read: if the account has no cluster of this name, this call creates the account workspace, its home, the Cluster record (spec.running=false) and the mounted child, then returns a kubeconfig. Idempotent - a second call finds everything and returns the same thing. Requires a service-auth JWT from the CALLER's own PDS; the account is the VERIFIED token's iss and is never read from this input. A cluster whose spec.running is false answers ClusterNotRunning; call createCluster or controlPlaneUp first. This call does not wake the control plane. The kubeconfig carries a client key and a short-lived x509 client certificate issued by the cluster's own OpenBao PKI. The key is made by OpenBao and returned only in this response; nothing stores it. ttlSeconds sets the certificate lifetime.",
"input": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["name"],
"properties": {
"name": {
"type": "string",
"description": "The cluster label, unique within the calling account. RFC-1123 label, <=63 characters."
},
"ttlSeconds": {
"type": "integer",
"minimum": 60,
"maximum": 86400,
"description": "Lifetime of the client certificate in seconds. Absent is 28800 (8 h). Below 60 or above 86400 is InvalidRequest: refused, never clamped. Never together with noExpiry."
},
"noExpiry": {
"type": "boolean",
"default": false,
"description": "Issue a certificate with no expiry (NotAfter 9999-12-31T23:59:59Z truncated to the cluster CA). It ends only by revocation (revokeIdentity), deleteCluster, or the CA expiring. Never together with ttlSeconds."
}
}
}
},
"output": {
"encoding": "application/json",
"schema": {
"type": "object",
"required": ["kubeconfig", "instance"],
"properties": {
"kubeconfig": {
"type": "string",
"description": "The whole kubeconfig, as YAML text. users[0].user holds client-certificate-data and client-key-data; there is no exec block and no token. The certificate's CN is the caller DID and its O is socialweb.computer:cluster-owners. Keep the file mode 0600; never commit it."
},
"instance": {
"type": "string",
"description": "status.instance: the opaque per-materialisation generation id of the cluster this kubeconfig points at. Retain it - a cached kubeconfig whose instance no longer matches must not be reused, and a new instance exists after every delete-then-recreate; controlPlaneDown and controlPlaneUp and a gateway restart keep the instance, because the cluster keeps its CA and state."
}
}
}
},
"errors": [
{ "name": "InvalidRequest", "description": "Name absent, or not a legal RFC-1123 label within 63 characters." },
{ "name": "Unauthorized", "description": "Missing or invalid service-auth token. Also returned when the token's aud is not this service or its lxm is not this method." },
{ "name": "IdentityRevoked", "description": "The caller's identity carries a deny record for this account. The deny is written before any deletion, so it refuses while the revocation is still propagating." },
{ "name": "ClusterNotFound", "description": "This account has no cluster of that name. Deliberately indistinguishable from a name that belongs to another account." },
{ "name": "ClusterNotRunning", "description": "The cluster exists but spec.running is false. Call createCluster or controlPlaneUp, then call this again." },
{ "name": "ClusterInitializing", "description": "The control plane or its vault is coming up. Retry after the Retry-After header." }
]
}
}
}