Deployment and lifecycle management for Nix
1{
2 "components": {
3 "responses": {},
4 "schemas": {
5 "GardenRegistration": {
6 "description": "HTTP registration request for a new garden",
7 "properties": {
8 "name": {
9 "description": "Name of garden",
10 "type": "string",
11 "x-struct": null,
12 "x-validate": null
13 },
14 "public_key": {
15 "description": "PEM-encoded RSA public key for private_key_jwt authentication",
16 "type": "string",
17 "x-struct": null,
18 "x-validate": null
19 }
20 },
21 "required": [
22 "name",
23 "public_key"
24 ],
25 "title": "GardenRegistration",
26 "type": "object",
27 "x-struct": "Elixir.SowerClient.GardenRegistration",
28 "x-validate": null
29 },
30 "Nix Cache": {
31 "description": "A Nix binary cache",
32 "example": {
33 "public_key": "my.cache.org:1111111111111111",
34 "sid": "example4ser3adju75ddusbr",
35 "url": "https://my.cache.org"
36 },
37 "properties": {
38 "public_key": {
39 "description": "Trusted public key for signed NARs",
40 "type": "string",
41 "x-struct": null,
42 "x-validate": null
43 },
44 "sid": {
45 "description": "sid of the nix cache",
46 "readOnly": true,
47 "type": "string",
48 "x-struct": null,
49 "x-validate": null
50 },
51 "url": {
52 "description": "URL to binary cache",
53 "type": "string",
54 "x-struct": null,
55 "x-validate": null
56 }
57 },
58 "required": [
59 "name",
60 "seed_type"
61 ],
62 "title": "Nix Cache",
63 "type": "object",
64 "x-struct": "Elixir.SowerClient.Nix.Cache",
65 "x-validate": null
66 },
67 "OAuthCredentials": {
68 "description": "OAuth client registration returned to a garden after registration",
69 "properties": {
70 "client_id": {
71 "description": "Boruta OAuth client ID",
72 "type": "string",
73 "x-struct": null,
74 "x-validate": null
75 }
76 },
77 "required": [
78 "client_id"
79 ],
80 "title": "OAuthCredentials",
81 "type": "object",
82 "x-struct": "Elixir.SowerClient.Auth.OAuthCredentials",
83 "x-validate": null
84 },
85 "Seed": {
86 "description": "A seed is an installable unit",
87 "example": {
88 "artifact": "/nix/store/aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa-nixos",
89 "name": "myhost",
90 "seed_type": "nixos",
91 "sid": "example4ser3adju75ddusbr",
92 "tags": []
93 },
94 "properties": {
95 "artifact": {
96 "description": "Artifact of the seed",
97 "type": "string",
98 "x-struct": null,
99 "x-validate": null
100 },
101 "name": {
102 "description": "Name of the seed",
103 "type": "string",
104 "x-struct": null,
105 "x-validate": null
106 },
107 "seed_type": {
108 "description": "Type of the seed",
109 "enum": [
110 "nixos",
111 "home-manager",
112 "nix-darwin",
113 "service"
114 ],
115 "type": "string",
116 "x-struct": null,
117 "x-validate": null
118 },
119 "sid": {
120 "description": "sid of the seed set by the server",
121 "nullable": true,
122 "readOnly": true,
123 "type": "string",
124 "x-struct": null,
125 "x-validate": null
126 },
127 "tags": {
128 "default": [],
129 "description": "Tags associated with the seed",
130 "items": {
131 "$ref": "#/components/schemas/SeedTag"
132 },
133 "type": "array",
134 "x-struct": null,
135 "x-validate": null
136 }
137 },
138 "required": [
139 "name",
140 "seed_type",
141 "artifact"
142 ],
143 "title": "Seed",
144 "type": "object",
145 "x-struct": "Elixir.SowerClient.Seed",
146 "x-validate": null
147 },
148 "SeedTag": {
149 "description": "A tag associated with a seed",
150 "example": {
151 "key": "environment",
152 "value": "production"
153 },
154 "properties": {
155 "key": {
156 "description": "Tag key",
157 "type": "string",
158 "x-struct": null,
159 "x-validate": null
160 },
161 "value": {
162 "description": "Tag value",
163 "type": "string",
164 "x-struct": null,
165 "x-validate": null
166 }
167 },
168 "required": [
169 "key",
170 "value"
171 ],
172 "title": "SeedTag",
173 "type": "object",
174 "x-struct": "Elixir.SowerClient.SeedTag",
175 "x-validate": null
176 },
177 "TokenInfo": {
178 "description": "Information about an authenticated access token",
179 "example": {
180 "description": "CI/CD token",
181 "expires_at": "2025-12-31",
182 "permissions": [
183 "seed:read",
184 "seed:write"
185 ],
186 "sid": "example4ser3adju75ddusbr"
187 },
188 "properties": {
189 "description": {
190 "description": "Human-readable token description",
191 "type": "string",
192 "x-struct": null,
193 "x-validate": null
194 },
195 "expires_at": {
196 "description": "Token expiration date",
197 "format": "date",
198 "type": "string",
199 "x-struct": null,
200 "x-validate": null
201 },
202 "permissions": {
203 "description": "Permission roles (e.g., seed:read, seed:write)",
204 "items": {
205 "type": "string",
206 "x-struct": null,
207 "x-validate": null
208 },
209 "type": "array",
210 "x-struct": null,
211 "x-validate": null
212 },
213 "sid": {
214 "description": "Token identifier",
215 "type": "string",
216 "x-struct": null,
217 "x-validate": null
218 }
219 },
220 "required": [
221 "sid",
222 "description",
223 "permissions",
224 "expires_at"
225 ],
226 "title": "TokenInfo",
227 "type": "object",
228 "x-struct": "Elixir.SowerClient.Auth.TokenInfo",
229 "x-validate": null
230 }
231 },
232 "securitySchemes": {
233 "authorization": {
234 "bearerFormat": "sower",
235 "description": "sower api token",
236 "scheme": "bearer",
237 "type": "http"
238 }
239 }
240 },
241 "info": {
242 "title": "sower",
243 "version": "0.8.0"
244 },
245 "openapi": "3.0.0",
246 "paths": {
247 "/api/v1/auth/verify": {
248 "get": {
249 "callbacks": {},
250 "description": "Validates the Bearer token and returns token metadata",
251 "operationId": "VerifyToken",
252 "parameters": [],
253 "responses": {
254 "200": {
255 "content": {
256 "application/json": {
257 "schema": {
258 "$ref": "#/components/schemas/TokenInfo"
259 }
260 }
261 },
262 "description": "Token info response"
263 },
264 "401": {
265 "content": {
266 "application/json": {
267 "schema": {
268 "properties": {
269 "error": {
270 "type": "string",
271 "x-struct": null,
272 "x-validate": null
273 }
274 },
275 "type": "object",
276 "x-struct": null,
277 "x-validate": null
278 }
279 }
280 },
281 "description": "Unauthorized"
282 }
283 },
284 "summary": "Verify access token",
285 "tags": []
286 }
287 },
288 "/api/v1/gardens/register": {
289 "post": {
290 "callbacks": {},
291 "operationId": "RegisterGarden",
292 "parameters": [],
293 "requestBody": {
294 "content": {
295 "application/json": {
296 "schema": {
297 "$ref": "#/components/schemas/GardenRegistration"
298 }
299 }
300 },
301 "description": "Garden registration params",
302 "required": false
303 },
304 "responses": {
305 "201": {
306 "content": {
307 "application/json": {
308 "schema": {
309 "properties": {
310 "oauth_credentials": {
311 "$ref": "#/components/schemas/OAuthCredentials"
312 },
313 "sid": {
314 "description": "Garden SID",
315 "type": "string",
316 "x-struct": null,
317 "x-validate": null
318 }
319 },
320 "required": [
321 "sid",
322 "oauth_credentials"
323 ],
324 "type": "object",
325 "x-struct": null,
326 "x-validate": null
327 }
328 }
329 },
330 "description": "Garden registration response"
331 },
332 "401": {
333 "content": {
334 "application/json": {
335 "schema": {
336 "properties": {
337 "error": {
338 "type": "string",
339 "x-struct": null,
340 "x-validate": null
341 }
342 },
343 "type": "object",
344 "x-struct": null,
345 "x-validate": null
346 }
347 }
348 },
349 "description": "Unauthorized"
350 },
351 "422": {
352 "content": {
353 "application/json": {
354 "schema": {
355 "properties": {
356 "error": {
357 "type": "string",
358 "x-struct": null,
359 "x-validate": null
360 }
361 },
362 "type": "object",
363 "x-struct": null,
364 "x-validate": null
365 }
366 }
367 },
368 "description": "Validation error"
369 }
370 },
371 "summary": "Register a new garden",
372 "tags": []
373 }
374 },
375 "/api/v1/nix/caches": {
376 "get": {
377 "callbacks": {},
378 "operationId": "ListNixCaches",
379 "parameters": [],
380 "responses": {
381 "200": {
382 "content": {
383 "application/json": {
384 "schema": {
385 "items": {
386 "$ref": "#/components/schemas/Nix Cache"
387 },
388 "type": "array",
389 "x-struct": null,
390 "x-validate": null
391 }
392 }
393 },
394 "description": "Nix Cache response"
395 },
396 "401": {
397 "content": {
398 "application/json": {
399 "schema": {
400 "properties": {
401 "error": {
402 "type": "string",
403 "x-struct": null,
404 "x-validate": null
405 }
406 },
407 "type": "object",
408 "x-struct": null,
409 "x-validate": null
410 }
411 }
412 },
413 "description": "Unauthorized"
414 }
415 },
416 "summary": "List Nix Caches",
417 "tags": []
418 }
419 },
420 "/api/v1/seeds": {
421 "get": {
422 "callbacks": {},
423 "operationId": "ListSeeds",
424 "parameters": [
425 {
426 "description": "Seed name",
427 "example": "host1",
428 "in": "query",
429 "name": "name",
430 "required": false,
431 "schema": {
432 "type": "string",
433 "x-struct": null,
434 "x-validate": null
435 }
436 },
437 {
438 "description": "Seed type, one of [nixos, home-manager, nix-darwin, service]",
439 "example": "nixos",
440 "in": "query",
441 "name": "seed_type",
442 "required": false,
443 "schema": {
444 "type": "string",
445 "x-struct": null,
446 "x-validate": null
447 }
448 }
449 ],
450 "responses": {
451 "200": {
452 "content": {
453 "application/json": {
454 "schema": {
455 "items": {
456 "$ref": "#/components/schemas/Seed"
457 },
458 "type": "array",
459 "x-struct": null,
460 "x-validate": null
461 }
462 }
463 },
464 "description": "Seed response"
465 },
466 "401": {
467 "content": {
468 "application/json": {
469 "schema": {
470 "properties": {
471 "error": {
472 "type": "string",
473 "x-struct": null,
474 "x-validate": null
475 }
476 },
477 "type": "object",
478 "x-struct": null,
479 "x-validate": null
480 }
481 }
482 },
483 "description": "Unauthorized"
484 },
485 "404": {
486 "content": {
487 "application/json": {
488 "schema": {
489 "properties": {
490 "error": {
491 "type": "string",
492 "x-struct": null,
493 "x-validate": null
494 }
495 },
496 "type": "object",
497 "x-struct": null,
498 "x-validate": null
499 }
500 }
501 },
502 "description": "Seed error response"
503 }
504 },
505 "summary": "List Seeds",
506 "tags": []
507 },
508 "post": {
509 "callbacks": {},
510 "operationId": "NewSeed",
511 "parameters": [
512 {
513 "description": "Rename the seed if matching artifact found",
514 "example": "true",
515 "in": "query",
516 "name": "rename",
517 "required": false,
518 "schema": {
519 "type": "boolean",
520 "x-struct": null,
521 "x-validate": null
522 }
523 }
524 ],
525 "requestBody": {
526 "content": {
527 "application/json": {
528 "schema": {
529 "$ref": "#/components/schemas/Seed"
530 }
531 }
532 },
533 "description": "Seed params",
534 "required": false
535 },
536 "responses": {
537 "201": {
538 "content": {
539 "application/json": {
540 "schema": {
541 "$ref": "#/components/schemas/Seed"
542 }
543 }
544 },
545 "description": "Seed response"
546 },
547 "401": {
548 "content": {
549 "application/json": {
550 "schema": {
551 "properties": {
552 "error": {
553 "type": "string",
554 "x-struct": null,
555 "x-validate": null
556 }
557 },
558 "type": "object",
559 "x-struct": null,
560 "x-validate": null
561 }
562 }
563 },
564 "description": "Unauthorized"
565 },
566 "409": {
567 "content": {
568 "application/json": {
569 "schema": {
570 "properties": {
571 "error": {
572 "type": "string",
573 "x-struct": null,
574 "x-validate": null
575 }
576 },
577 "type": "object",
578 "x-struct": null,
579 "x-validate": null
580 }
581 }
582 },
583 "description": "Seed conflict response"
584 }
585 },
586 "summary": "New Seed",
587 "tags": []
588 }
589 },
590 "/api/v1/seeds/latest": {
591 "get": {
592 "callbacks": {},
593 "operationId": "LatestSeed",
594 "parameters": [
595 {
596 "description": "Filter by tags (key=value format, can repeat)",
597 "in": "query",
598 "name": "tags",
599 "required": false,
600 "schema": {
601 "items": {
602 "type": "string",
603 "x-struct": null,
604 "x-validate": null
605 },
606 "type": "array",
607 "x-struct": null,
608 "x-validate": null
609 }
610 },
611 {
612 "description": "Seed name",
613 "example": "host1",
614 "in": "query",
615 "name": "name",
616 "required": false,
617 "schema": {
618 "type": "string",
619 "x-struct": null,
620 "x-validate": null
621 }
622 },
623 {
624 "description": "Seed type",
625 "example": "nixos",
626 "in": "query",
627 "name": "seed_type",
628 "required": false,
629 "schema": {
630 "type": "string",
631 "x-struct": null,
632 "x-validate": null
633 }
634 }
635 ],
636 "responses": {
637 "200": {
638 "content": {
639 "application/json": {
640 "schema": {
641 "$ref": "#/components/schemas/Seed"
642 }
643 }
644 },
645 "description": "Seed response"
646 },
647 "401": {
648 "content": {
649 "application/json": {
650 "schema": {
651 "properties": {
652 "error": {
653 "type": "string",
654 "x-struct": null,
655 "x-validate": null
656 }
657 },
658 "type": "object",
659 "x-struct": null,
660 "x-validate": null
661 }
662 }
663 },
664 "description": "Unauthorized"
665 },
666 "404": {
667 "content": {
668 "application/json": {
669 "schema": {
670 "properties": {
671 "error": {
672 "type": "string",
673 "x-struct": null,
674 "x-validate": null
675 }
676 },
677 "type": "object",
678 "x-struct": null,
679 "x-validate": null
680 }
681 }
682 },
683 "description": "Seed error response"
684 }
685 },
686 "summary": "Find latest Seed",
687 "tags": []
688 }
689 },
690 "/api/v1/seeds/{sid}": {
691 "get": {
692 "callbacks": {},
693 "operationId": "GetSeed",
694 "parameters": [
695 {
696 "description": "Seed SID",
697 "example": "example4ser3adju75ddusbr",
698 "in": "path",
699 "name": "sid",
700 "required": true,
701 "schema": {
702 "type": "string",
703 "x-struct": null,
704 "x-validate": null
705 }
706 }
707 ],
708 "responses": {
709 "200": {
710 "content": {
711 "application/json": {
712 "schema": {
713 "$ref": "#/components/schemas/Seed"
714 }
715 }
716 },
717 "description": "Seed response"
718 },
719 "401": {
720 "content": {
721 "application/json": {
722 "schema": {
723 "properties": {
724 "error": {
725 "type": "string",
726 "x-struct": null,
727 "x-validate": null
728 }
729 },
730 "type": "object",
731 "x-struct": null,
732 "x-validate": null
733 }
734 }
735 },
736 "description": "Unauthorized"
737 },
738 "404": {
739 "content": {
740 "application/json": {
741 "schema": {
742 "properties": {
743 "error": {
744 "type": "string",
745 "x-struct": null,
746 "x-validate": null
747 }
748 },
749 "type": "object",
750 "x-struct": null,
751 "x-validate": null
752 }
753 }
754 },
755 "description": "Seed error response"
756 }
757 },
758 "summary": "Get Seed",
759 "tags": []
760 }
761 }
762 },
763 "security": [
764 {
765 "authorization": []
766 }
767 ],
768 "servers": [
769 {
770 "url": "http://localhost:4002"
771 }
772 ],
773 "tags": []
774}