@fntio/infra-client 0.0.0-stage → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +193 -0
- package/LICENSE +93 -0
- package/README.md +875 -2
- package/assets/acl-reconciler/index.js +1604 -0
- package/assets/api/index.js +9857 -0
- package/assets/api/package.json +9 -0
- package/assets/api/vendor_modules/.package-lock.json +857 -0
- package/assets/api/vendor_modules/accepts/HISTORY.md +243 -0
- package/assets/api/vendor_modules/accepts/LICENSE +23 -0
- package/assets/api/vendor_modules/accepts/README.md +140 -0
- package/assets/api/vendor_modules/accepts/index.js +238 -0
- package/assets/api/vendor_modules/accepts/package.json +47 -0
- package/assets/api/vendor_modules/array-flatten/LICENSE +21 -0
- package/assets/api/vendor_modules/array-flatten/README.md +43 -0
- package/assets/api/vendor_modules/array-flatten/array-flatten.js +64 -0
- package/assets/api/vendor_modules/array-flatten/package.json +39 -0
- package/assets/api/vendor_modules/aws-jwt-verify/LICENSE +175 -0
- package/assets/api/vendor_modules/aws-jwt-verify/README.md +1033 -0
- package/assets/api/vendor_modules/aws-jwt-verify/asn1.d.ts +20 -0
- package/assets/api/vendor_modules/aws-jwt-verify/assert.d.ts +41 -0
- package/assets/api/vendor_modules/aws-jwt-verify/cognito-verifier.d.ts +183 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/asn1.js +301 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/assert.js +108 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/cognito-verifier.js +158 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/error.js +131 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/https-common.js +29 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/https-node.js +89 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/https.js +52 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/index.js +9 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/jwk.js +221 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/jwt-model.js +10 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/jwt-rsa.js +397 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/jwt.js +161 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/node-web-compat-node.js +48 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/node-web-compat-web.js +78 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/node-web-compat.js +11 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/package.json +1 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/safe-json-parse.js +34 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/cjs/typing-util.js +6 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/asn1.js +296 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/assert.js +101 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/cognito-verifier.js +153 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/error.js +101 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/https-common.js +25 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/https-node.js +85 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/https.js +48 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/index.js +4 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/jwk.js +208 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/jwt-model.js +7 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/jwt-rsa.js +389 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/jwt.js +156 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/node-web-compat-node.js +45 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/node-web-compat-web.js +75 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/node-web-compat.js +10 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/package.json +1 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/safe-json-parse.js +29 -0
- package/assets/api/vendor_modules/aws-jwt-verify/dist/esm/typing-util.js +5 -0
- package/assets/api/vendor_modules/aws-jwt-verify/error.d.ts +108 -0
- package/assets/api/vendor_modules/aws-jwt-verify/https-common.d.ts +9 -0
- package/assets/api/vendor_modules/aws-jwt-verify/https-node.d.ts +20 -0
- package/assets/api/vendor_modules/aws-jwt-verify/https.d.ts +35 -0
- package/assets/api/vendor_modules/aws-jwt-verify/index.d.ts +2 -0
- package/assets/api/vendor_modules/aws-jwt-verify/jwk.d.ts +76 -0
- package/assets/api/vendor_modules/aws-jwt-verify/jwt-model.d.ts +78 -0
- package/assets/api/vendor_modules/aws-jwt-verify/jwt-rsa.d.ts +348 -0
- package/assets/api/vendor_modules/aws-jwt-verify/jwt.d.ts +51 -0
- package/assets/api/vendor_modules/aws-jwt-verify/package.json +136 -0
- package/assets/api/vendor_modules/aws-jwt-verify/safe-json-parse.d.ts +18 -0
- package/assets/api/vendor_modules/aws-jwt-verify/typing-util.d.ts +38 -0
- package/assets/api/vendor_modules/body-parser/HISTORY.md +703 -0
- package/assets/api/vendor_modules/body-parser/LICENSE +23 -0
- package/assets/api/vendor_modules/body-parser/README.md +476 -0
- package/assets/api/vendor_modules/body-parser/index.js +156 -0
- package/assets/api/vendor_modules/body-parser/lib/read.js +205 -0
- package/assets/api/vendor_modules/body-parser/lib/types/json.js +247 -0
- package/assets/api/vendor_modules/body-parser/lib/types/raw.js +105 -0
- package/assets/api/vendor_modules/body-parser/lib/types/text.js +125 -0
- package/assets/api/vendor_modules/body-parser/lib/types/urlencoded.js +303 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/.editorconfig +46 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/.github/SECURITY.md +11 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/.github/THREAT_MODEL.md +80 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/.nycrc +13 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/CHANGELOG.md +872 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/LICENSE.md +29 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/README.md +804 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/dist/qs.js +141 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/eslint.config.mjs +57 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/lib/formats.js +23 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/lib/index.js +11 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/lib/parse.js +503 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/lib/stringify.js +378 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/lib/utils.js +512 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/package.json +95 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/test/empty-keys-cases.js +267 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/test/parse.js +2296 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/test/stringify.js +1995 -0
- package/assets/api/vendor_modules/body-parser/node_modules/qs/test/utils.js +822 -0
- package/assets/api/vendor_modules/body-parser/package.json +55 -0
- package/assets/api/vendor_modules/bytes/History.md +97 -0
- package/assets/api/vendor_modules/bytes/LICENSE +23 -0
- package/assets/api/vendor_modules/bytes/Readme.md +152 -0
- package/assets/api/vendor_modules/bytes/index.js +170 -0
- package/assets/api/vendor_modules/bytes/package.json +42 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/.eslintrc +17 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/.nycrc +9 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/CHANGELOG.md +30 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/LICENSE +21 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/README.md +62 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/actualApply.d.ts +1 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/actualApply.js +10 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/applyBind.d.ts +19 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/applyBind.js +10 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/functionApply.d.ts +1 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/functionApply.js +4 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/functionCall.d.ts +1 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/functionCall.js +4 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/index.d.ts +64 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/index.js +15 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/package.json +85 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/reflectApply.d.ts +3 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/reflectApply.js +4 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/test/index.js +63 -0
- package/assets/api/vendor_modules/call-bind-apply-helpers/tsconfig.json +9 -0
- package/assets/api/vendor_modules/call-bound/.eslintrc +13 -0
- package/assets/api/vendor_modules/call-bound/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/call-bound/.nycrc +9 -0
- package/assets/api/vendor_modules/call-bound/CHANGELOG.md +42 -0
- package/assets/api/vendor_modules/call-bound/LICENSE +21 -0
- package/assets/api/vendor_modules/call-bound/README.md +53 -0
- package/assets/api/vendor_modules/call-bound/index.d.ts +94 -0
- package/assets/api/vendor_modules/call-bound/index.js +19 -0
- package/assets/api/vendor_modules/call-bound/package.json +99 -0
- package/assets/api/vendor_modules/call-bound/test/index.js +61 -0
- package/assets/api/vendor_modules/call-bound/tsconfig.json +10 -0
- package/assets/api/vendor_modules/content-disposition/HISTORY.md +60 -0
- package/assets/api/vendor_modules/content-disposition/LICENSE +22 -0
- package/assets/api/vendor_modules/content-disposition/README.md +142 -0
- package/assets/api/vendor_modules/content-disposition/index.js +458 -0
- package/assets/api/vendor_modules/content-disposition/package.json +44 -0
- package/assets/api/vendor_modules/content-type/HISTORY.md +29 -0
- package/assets/api/vendor_modules/content-type/LICENSE +22 -0
- package/assets/api/vendor_modules/content-type/README.md +94 -0
- package/assets/api/vendor_modules/content-type/index.js +225 -0
- package/assets/api/vendor_modules/content-type/package.json +42 -0
- package/assets/api/vendor_modules/cookie/LICENSE +24 -0
- package/assets/api/vendor_modules/cookie/README.md +317 -0
- package/assets/api/vendor_modules/cookie/SECURITY.md +25 -0
- package/assets/api/vendor_modules/cookie/index.js +335 -0
- package/assets/api/vendor_modules/cookie/package.json +44 -0
- package/assets/api/vendor_modules/cookie-signature/History.md +42 -0
- package/assets/api/vendor_modules/cookie-signature/Readme.md +42 -0
- package/assets/api/vendor_modules/cookie-signature/index.js +51 -0
- package/assets/api/vendor_modules/cookie-signature/package.json +18 -0
- package/assets/api/vendor_modules/debug/.coveralls.yml +1 -0
- package/assets/api/vendor_modules/debug/.eslintrc +11 -0
- package/assets/api/vendor_modules/debug/.travis.yml +14 -0
- package/assets/api/vendor_modules/debug/CHANGELOG.md +362 -0
- package/assets/api/vendor_modules/debug/LICENSE +19 -0
- package/assets/api/vendor_modules/debug/Makefile +50 -0
- package/assets/api/vendor_modules/debug/README.md +312 -0
- package/assets/api/vendor_modules/debug/component.json +19 -0
- package/assets/api/vendor_modules/debug/karma.conf.js +70 -0
- package/assets/api/vendor_modules/debug/node.js +1 -0
- package/assets/api/vendor_modules/debug/package.json +49 -0
- package/assets/api/vendor_modules/debug/src/browser.js +185 -0
- package/assets/api/vendor_modules/debug/src/debug.js +202 -0
- package/assets/api/vendor_modules/debug/src/index.js +10 -0
- package/assets/api/vendor_modules/debug/src/inspector-log.js +15 -0
- package/assets/api/vendor_modules/debug/src/node.js +248 -0
- package/assets/api/vendor_modules/depd/History.md +103 -0
- package/assets/api/vendor_modules/depd/LICENSE +22 -0
- package/assets/api/vendor_modules/depd/Readme.md +280 -0
- package/assets/api/vendor_modules/depd/index.js +538 -0
- package/assets/api/vendor_modules/depd/lib/browser/index.js +77 -0
- package/assets/api/vendor_modules/depd/package.json +45 -0
- package/assets/api/vendor_modules/destroy/LICENSE +23 -0
- package/assets/api/vendor_modules/destroy/README.md +63 -0
- package/assets/api/vendor_modules/destroy/index.js +209 -0
- package/assets/api/vendor_modules/destroy/package.json +48 -0
- package/assets/api/vendor_modules/dunder-proto/.eslintrc +5 -0
- package/assets/api/vendor_modules/dunder-proto/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/dunder-proto/.nycrc +13 -0
- package/assets/api/vendor_modules/dunder-proto/CHANGELOG.md +24 -0
- package/assets/api/vendor_modules/dunder-proto/LICENSE +21 -0
- package/assets/api/vendor_modules/dunder-proto/README.md +54 -0
- package/assets/api/vendor_modules/dunder-proto/get.d.ts +5 -0
- package/assets/api/vendor_modules/dunder-proto/get.js +30 -0
- package/assets/api/vendor_modules/dunder-proto/package.json +76 -0
- package/assets/api/vendor_modules/dunder-proto/set.d.ts +5 -0
- package/assets/api/vendor_modules/dunder-proto/set.js +35 -0
- package/assets/api/vendor_modules/dunder-proto/test/get.js +34 -0
- package/assets/api/vendor_modules/dunder-proto/test/index.js +4 -0
- package/assets/api/vendor_modules/dunder-proto/test/set.js +50 -0
- package/assets/api/vendor_modules/dunder-proto/tsconfig.json +9 -0
- package/assets/api/vendor_modules/ee-first/LICENSE +22 -0
- package/assets/api/vendor_modules/ee-first/README.md +80 -0
- package/assets/api/vendor_modules/ee-first/index.js +95 -0
- package/assets/api/vendor_modules/ee-first/package.json +29 -0
- package/assets/api/vendor_modules/encodeurl/LICENSE +22 -0
- package/assets/api/vendor_modules/encodeurl/README.md +109 -0
- package/assets/api/vendor_modules/encodeurl/index.js +60 -0
- package/assets/api/vendor_modules/encodeurl/package.json +40 -0
- package/assets/api/vendor_modules/es-define-property/.eslintrc +13 -0
- package/assets/api/vendor_modules/es-define-property/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/es-define-property/.nycrc +9 -0
- package/assets/api/vendor_modules/es-define-property/CHANGELOG.md +29 -0
- package/assets/api/vendor_modules/es-define-property/LICENSE +21 -0
- package/assets/api/vendor_modules/es-define-property/README.md +49 -0
- package/assets/api/vendor_modules/es-define-property/index.d.ts +3 -0
- package/assets/api/vendor_modules/es-define-property/index.js +14 -0
- package/assets/api/vendor_modules/es-define-property/package.json +81 -0
- package/assets/api/vendor_modules/es-define-property/test/index.js +56 -0
- package/assets/api/vendor_modules/es-define-property/tsconfig.json +10 -0
- package/assets/api/vendor_modules/es-errors/.eslintrc +5 -0
- package/assets/api/vendor_modules/es-errors/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/es-errors/CHANGELOG.md +40 -0
- package/assets/api/vendor_modules/es-errors/LICENSE +21 -0
- package/assets/api/vendor_modules/es-errors/README.md +55 -0
- package/assets/api/vendor_modules/es-errors/eval.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/eval.js +4 -0
- package/assets/api/vendor_modules/es-errors/index.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/index.js +4 -0
- package/assets/api/vendor_modules/es-errors/package.json +80 -0
- package/assets/api/vendor_modules/es-errors/range.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/range.js +4 -0
- package/assets/api/vendor_modules/es-errors/ref.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/ref.js +4 -0
- package/assets/api/vendor_modules/es-errors/syntax.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/syntax.js +4 -0
- package/assets/api/vendor_modules/es-errors/test/index.js +19 -0
- package/assets/api/vendor_modules/es-errors/tsconfig.json +49 -0
- package/assets/api/vendor_modules/es-errors/type.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/type.js +4 -0
- package/assets/api/vendor_modules/es-errors/uri.d.ts +3 -0
- package/assets/api/vendor_modules/es-errors/uri.js +4 -0
- package/assets/api/vendor_modules/es-object-atoms/.eslintrc +16 -0
- package/assets/api/vendor_modules/es-object-atoms/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/es-object-atoms/CHANGELOG.md +44 -0
- package/assets/api/vendor_modules/es-object-atoms/LICENSE +21 -0
- package/assets/api/vendor_modules/es-object-atoms/README.md +63 -0
- package/assets/api/vendor_modules/es-object-atoms/RequireObjectCoercible.d.ts +3 -0
- package/assets/api/vendor_modules/es-object-atoms/RequireObjectCoercible.js +11 -0
- package/assets/api/vendor_modules/es-object-atoms/ToObject.d.ts +7 -0
- package/assets/api/vendor_modules/es-object-atoms/ToObject.js +10 -0
- package/assets/api/vendor_modules/es-object-atoms/index.d.ts +3 -0
- package/assets/api/vendor_modules/es-object-atoms/index.js +4 -0
- package/assets/api/vendor_modules/es-object-atoms/isObject.d.ts +3 -0
- package/assets/api/vendor_modules/es-object-atoms/isObject.js +6 -0
- package/assets/api/vendor_modules/es-object-atoms/package.json +79 -0
- package/assets/api/vendor_modules/es-object-atoms/test/index.js +38 -0
- package/assets/api/vendor_modules/es-object-atoms/tsconfig.json +7 -0
- package/assets/api/vendor_modules/escape-html/LICENSE +24 -0
- package/assets/api/vendor_modules/escape-html/Readme.md +43 -0
- package/assets/api/vendor_modules/escape-html/index.js +78 -0
- package/assets/api/vendor_modules/escape-html/package.json +24 -0
- package/assets/api/vendor_modules/etag/HISTORY.md +83 -0
- package/assets/api/vendor_modules/etag/LICENSE +22 -0
- package/assets/api/vendor_modules/etag/README.md +159 -0
- package/assets/api/vendor_modules/etag/index.js +131 -0
- package/assets/api/vendor_modules/etag/package.json +47 -0
- package/assets/api/vendor_modules/express/History.md +3676 -0
- package/assets/api/vendor_modules/express/LICENSE +24 -0
- package/assets/api/vendor_modules/express/Readme.md +260 -0
- package/assets/api/vendor_modules/express/index.js +11 -0
- package/assets/api/vendor_modules/express/lib/application.js +661 -0
- package/assets/api/vendor_modules/express/lib/express.js +116 -0
- package/assets/api/vendor_modules/express/lib/middleware/init.js +43 -0
- package/assets/api/vendor_modules/express/lib/middleware/query.js +47 -0
- package/assets/api/vendor_modules/express/lib/request.js +525 -0
- package/assets/api/vendor_modules/express/lib/response.js +1179 -0
- package/assets/api/vendor_modules/express/lib/router/index.js +673 -0
- package/assets/api/vendor_modules/express/lib/router/layer.js +181 -0
- package/assets/api/vendor_modules/express/lib/router/route.js +230 -0
- package/assets/api/vendor_modules/express/lib/utils.js +304 -0
- package/assets/api/vendor_modules/express/lib/view.js +182 -0
- package/assets/api/vendor_modules/express/package.json +102 -0
- package/assets/api/vendor_modules/finalhandler/HISTORY.md +216 -0
- package/assets/api/vendor_modules/finalhandler/LICENSE +22 -0
- package/assets/api/vendor_modules/finalhandler/README.md +147 -0
- package/assets/api/vendor_modules/finalhandler/SECURITY.md +25 -0
- package/assets/api/vendor_modules/finalhandler/index.js +341 -0
- package/assets/api/vendor_modules/finalhandler/package.json +47 -0
- package/assets/api/vendor_modules/forwarded/HISTORY.md +21 -0
- package/assets/api/vendor_modules/forwarded/LICENSE +22 -0
- package/assets/api/vendor_modules/forwarded/README.md +57 -0
- package/assets/api/vendor_modules/forwarded/index.js +90 -0
- package/assets/api/vendor_modules/forwarded/package.json +45 -0
- package/assets/api/vendor_modules/fresh/HISTORY.md +70 -0
- package/assets/api/vendor_modules/fresh/LICENSE +23 -0
- package/assets/api/vendor_modules/fresh/README.md +119 -0
- package/assets/api/vendor_modules/fresh/index.js +137 -0
- package/assets/api/vendor_modules/fresh/package.json +46 -0
- package/assets/api/vendor_modules/function-bind/.eslintrc +21 -0
- package/assets/api/vendor_modules/function-bind/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/function-bind/.github/SECURITY.md +3 -0
- package/assets/api/vendor_modules/function-bind/.nycrc +13 -0
- package/assets/api/vendor_modules/function-bind/CHANGELOG.md +136 -0
- package/assets/api/vendor_modules/function-bind/LICENSE +20 -0
- package/assets/api/vendor_modules/function-bind/README.md +46 -0
- package/assets/api/vendor_modules/function-bind/implementation.js +84 -0
- package/assets/api/vendor_modules/function-bind/index.js +5 -0
- package/assets/api/vendor_modules/function-bind/package.json +87 -0
- package/assets/api/vendor_modules/function-bind/test/.eslintrc +9 -0
- package/assets/api/vendor_modules/function-bind/test/index.js +252 -0
- package/assets/api/vendor_modules/get-intrinsic/.eslintrc +42 -0
- package/assets/api/vendor_modules/get-intrinsic/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/get-intrinsic/.nycrc +9 -0
- package/assets/api/vendor_modules/get-intrinsic/CHANGELOG.md +186 -0
- package/assets/api/vendor_modules/get-intrinsic/LICENSE +21 -0
- package/assets/api/vendor_modules/get-intrinsic/README.md +71 -0
- package/assets/api/vendor_modules/get-intrinsic/index.js +378 -0
- package/assets/api/vendor_modules/get-intrinsic/package.json +97 -0
- package/assets/api/vendor_modules/get-intrinsic/test/GetIntrinsic.js +274 -0
- package/assets/api/vendor_modules/get-proto/.eslintrc +10 -0
- package/assets/api/vendor_modules/get-proto/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/get-proto/.nycrc +9 -0
- package/assets/api/vendor_modules/get-proto/CHANGELOG.md +21 -0
- package/assets/api/vendor_modules/get-proto/LICENSE +21 -0
- package/assets/api/vendor_modules/get-proto/Object.getPrototypeOf.d.ts +5 -0
- package/assets/api/vendor_modules/get-proto/Object.getPrototypeOf.js +6 -0
- package/assets/api/vendor_modules/get-proto/README.md +50 -0
- package/assets/api/vendor_modules/get-proto/Reflect.getPrototypeOf.d.ts +3 -0
- package/assets/api/vendor_modules/get-proto/Reflect.getPrototypeOf.js +4 -0
- package/assets/api/vendor_modules/get-proto/index.d.ts +5 -0
- package/assets/api/vendor_modules/get-proto/index.js +27 -0
- package/assets/api/vendor_modules/get-proto/package.json +81 -0
- package/assets/api/vendor_modules/get-proto/test/index.js +68 -0
- package/assets/api/vendor_modules/get-proto/tsconfig.json +9 -0
- package/assets/api/vendor_modules/gopd/.eslintrc +16 -0
- package/assets/api/vendor_modules/gopd/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/gopd/CHANGELOG.md +45 -0
- package/assets/api/vendor_modules/gopd/LICENSE +21 -0
- package/assets/api/vendor_modules/gopd/README.md +40 -0
- package/assets/api/vendor_modules/gopd/gOPD.d.ts +1 -0
- package/assets/api/vendor_modules/gopd/gOPD.js +4 -0
- package/assets/api/vendor_modules/gopd/index.d.ts +5 -0
- package/assets/api/vendor_modules/gopd/index.js +15 -0
- package/assets/api/vendor_modules/gopd/package.json +77 -0
- package/assets/api/vendor_modules/gopd/test/index.js +36 -0
- package/assets/api/vendor_modules/gopd/tsconfig.json +9 -0
- package/assets/api/vendor_modules/has-symbols/.eslintrc +11 -0
- package/assets/api/vendor_modules/has-symbols/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/has-symbols/.nycrc +9 -0
- package/assets/api/vendor_modules/has-symbols/CHANGELOG.md +91 -0
- package/assets/api/vendor_modules/has-symbols/LICENSE +21 -0
- package/assets/api/vendor_modules/has-symbols/README.md +46 -0
- package/assets/api/vendor_modules/has-symbols/index.d.ts +3 -0
- package/assets/api/vendor_modules/has-symbols/index.js +14 -0
- package/assets/api/vendor_modules/has-symbols/package.json +111 -0
- package/assets/api/vendor_modules/has-symbols/shams.d.ts +3 -0
- package/assets/api/vendor_modules/has-symbols/shams.js +45 -0
- package/assets/api/vendor_modules/has-symbols/test/index.js +22 -0
- package/assets/api/vendor_modules/has-symbols/test/shams/core-js.js +29 -0
- package/assets/api/vendor_modules/has-symbols/test/shams/get-own-property-symbols.js +29 -0
- package/assets/api/vendor_modules/has-symbols/test/tests.js +58 -0
- package/assets/api/vendor_modules/has-symbols/tsconfig.json +10 -0
- package/assets/api/vendor_modules/hasown/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/hasown/.nycrc +13 -0
- package/assets/api/vendor_modules/hasown/CHANGELOG.md +58 -0
- package/assets/api/vendor_modules/hasown/LICENSE +21 -0
- package/assets/api/vendor_modules/hasown/README.md +40 -0
- package/assets/api/vendor_modules/hasown/eslint.config.mjs +6 -0
- package/assets/api/vendor_modules/hasown/index.d.ts +3 -0
- package/assets/api/vendor_modules/hasown/index.js +8 -0
- package/assets/api/vendor_modules/hasown/package.json +91 -0
- package/assets/api/vendor_modules/hasown/tsconfig.json +6 -0
- package/assets/api/vendor_modules/http-errors/HISTORY.md +186 -0
- package/assets/api/vendor_modules/http-errors/LICENSE +23 -0
- package/assets/api/vendor_modules/http-errors/README.md +169 -0
- package/assets/api/vendor_modules/http-errors/index.js +290 -0
- package/assets/api/vendor_modules/http-errors/package.json +54 -0
- package/assets/api/vendor_modules/iconv-lite/Changelog.md +162 -0
- package/assets/api/vendor_modules/iconv-lite/LICENSE +21 -0
- package/assets/api/vendor_modules/iconv-lite/README.md +156 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/dbcs-codec.js +555 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/dbcs-data.js +176 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/index.js +22 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/internal.js +188 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/sbcs-codec.js +72 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/sbcs-data-generated.js +451 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/sbcs-data.js +174 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/big5-added.json +122 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/cp936.json +264 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/cp949.json +273 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/cp950.json +177 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/eucjp.json +182 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/gb18030-ranges.json +1 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/gbk-added.json +55 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/tables/shiftjis.json +125 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/utf16.js +177 -0
- package/assets/api/vendor_modules/iconv-lite/encodings/utf7.js +290 -0
- package/assets/api/vendor_modules/iconv-lite/lib/bom-handling.js +52 -0
- package/assets/api/vendor_modules/iconv-lite/lib/extend-node.js +217 -0
- package/assets/api/vendor_modules/iconv-lite/lib/index.d.ts +24 -0
- package/assets/api/vendor_modules/iconv-lite/lib/index.js +153 -0
- package/assets/api/vendor_modules/iconv-lite/lib/streams.js +121 -0
- package/assets/api/vendor_modules/iconv-lite/package.json +46 -0
- package/assets/api/vendor_modules/inherits/LICENSE +16 -0
- package/assets/api/vendor_modules/inherits/README.md +42 -0
- package/assets/api/vendor_modules/inherits/inherits.js +9 -0
- package/assets/api/vendor_modules/inherits/inherits_browser.js +27 -0
- package/assets/api/vendor_modules/inherits/package.json +29 -0
- package/assets/api/vendor_modules/ipaddr.js/LICENSE +19 -0
- package/assets/api/vendor_modules/ipaddr.js/README.md +233 -0
- package/assets/api/vendor_modules/ipaddr.js/ipaddr.min.js +1 -0
- package/assets/api/vendor_modules/ipaddr.js/lib/ipaddr.js +673 -0
- package/assets/api/vendor_modules/ipaddr.js/lib/ipaddr.js.d.ts +68 -0
- package/assets/api/vendor_modules/ipaddr.js/package.json +35 -0
- package/assets/api/vendor_modules/math-intrinsics/.eslintrc +16 -0
- package/assets/api/vendor_modules/math-intrinsics/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/math-intrinsics/CHANGELOG.md +24 -0
- package/assets/api/vendor_modules/math-intrinsics/LICENSE +21 -0
- package/assets/api/vendor_modules/math-intrinsics/README.md +50 -0
- package/assets/api/vendor_modules/math-intrinsics/abs.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/abs.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/constants/maxArrayLength.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/constants/maxArrayLength.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/constants/maxSafeInteger.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/constants/maxSafeInteger.js +5 -0
- package/assets/api/vendor_modules/math-intrinsics/constants/maxValue.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/constants/maxValue.js +5 -0
- package/assets/api/vendor_modules/math-intrinsics/floor.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/floor.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/isFinite.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/isFinite.js +12 -0
- package/assets/api/vendor_modules/math-intrinsics/isInteger.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/isInteger.js +16 -0
- package/assets/api/vendor_modules/math-intrinsics/isNaN.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/isNaN.js +6 -0
- package/assets/api/vendor_modules/math-intrinsics/isNegativeZero.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/isNegativeZero.js +6 -0
- package/assets/api/vendor_modules/math-intrinsics/max.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/max.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/min.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/min.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/mod.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/mod.js +9 -0
- package/assets/api/vendor_modules/math-intrinsics/package.json +86 -0
- package/assets/api/vendor_modules/math-intrinsics/pow.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/pow.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/round.d.ts +1 -0
- package/assets/api/vendor_modules/math-intrinsics/round.js +4 -0
- package/assets/api/vendor_modules/math-intrinsics/sign.d.ts +3 -0
- package/assets/api/vendor_modules/math-intrinsics/sign.js +11 -0
- package/assets/api/vendor_modules/math-intrinsics/test/index.js +192 -0
- package/assets/api/vendor_modules/math-intrinsics/tsconfig.json +3 -0
- package/assets/api/vendor_modules/media-typer/HISTORY.md +22 -0
- package/assets/api/vendor_modules/media-typer/LICENSE +22 -0
- package/assets/api/vendor_modules/media-typer/README.md +81 -0
- package/assets/api/vendor_modules/media-typer/index.js +270 -0
- package/assets/api/vendor_modules/media-typer/package.json +26 -0
- package/assets/api/vendor_modules/merge-descriptors/HISTORY.md +21 -0
- package/assets/api/vendor_modules/merge-descriptors/LICENSE +23 -0
- package/assets/api/vendor_modules/merge-descriptors/README.md +49 -0
- package/assets/api/vendor_modules/merge-descriptors/index.js +60 -0
- package/assets/api/vendor_modules/merge-descriptors/package.json +39 -0
- package/assets/api/vendor_modules/methods/HISTORY.md +29 -0
- package/assets/api/vendor_modules/methods/LICENSE +24 -0
- package/assets/api/vendor_modules/methods/README.md +51 -0
- package/assets/api/vendor_modules/methods/index.js +69 -0
- package/assets/api/vendor_modules/methods/package.json +36 -0
- package/assets/api/vendor_modules/mime/CHANGELOG.md +164 -0
- package/assets/api/vendor_modules/mime/LICENSE +21 -0
- package/assets/api/vendor_modules/mime/README.md +90 -0
- package/assets/api/vendor_modules/mime/cli.js +8 -0
- package/assets/api/vendor_modules/mime/mime.js +108 -0
- package/assets/api/vendor_modules/mime/package.json +44 -0
- package/assets/api/vendor_modules/mime/src/build.js +53 -0
- package/assets/api/vendor_modules/mime/src/test.js +60 -0
- package/assets/api/vendor_modules/mime/types.json +1 -0
- package/assets/api/vendor_modules/mime-db/HISTORY.md +507 -0
- package/assets/api/vendor_modules/mime-db/LICENSE +23 -0
- package/assets/api/vendor_modules/mime-db/README.md +100 -0
- package/assets/api/vendor_modules/mime-db/db.json +8519 -0
- package/assets/api/vendor_modules/mime-db/index.js +12 -0
- package/assets/api/vendor_modules/mime-db/package.json +60 -0
- package/assets/api/vendor_modules/mime-types/HISTORY.md +397 -0
- package/assets/api/vendor_modules/mime-types/LICENSE +23 -0
- package/assets/api/vendor_modules/mime-types/README.md +113 -0
- package/assets/api/vendor_modules/mime-types/index.js +188 -0
- package/assets/api/vendor_modules/mime-types/package.json +44 -0
- package/assets/api/vendor_modules/ms/index.js +152 -0
- package/assets/api/vendor_modules/ms/license.md +21 -0
- package/assets/api/vendor_modules/ms/package.json +37 -0
- package/assets/api/vendor_modules/ms/readme.md +51 -0
- package/assets/api/vendor_modules/negotiator/HISTORY.md +108 -0
- package/assets/api/vendor_modules/negotiator/LICENSE +24 -0
- package/assets/api/vendor_modules/negotiator/README.md +203 -0
- package/assets/api/vendor_modules/negotiator/index.js +82 -0
- package/assets/api/vendor_modules/negotiator/lib/charset.js +169 -0
- package/assets/api/vendor_modules/negotiator/lib/encoding.js +184 -0
- package/assets/api/vendor_modules/negotiator/lib/language.js +179 -0
- package/assets/api/vendor_modules/negotiator/lib/mediaType.js +294 -0
- package/assets/api/vendor_modules/negotiator/package.json +42 -0
- package/assets/api/vendor_modules/object-inspect/.eslintrc +53 -0
- package/assets/api/vendor_modules/object-inspect/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/object-inspect/.nycrc +13 -0
- package/assets/api/vendor_modules/object-inspect/CHANGELOG.md +424 -0
- package/assets/api/vendor_modules/object-inspect/LICENSE +21 -0
- package/assets/api/vendor_modules/object-inspect/example/all.js +23 -0
- package/assets/api/vendor_modules/object-inspect/example/circular.js +6 -0
- package/assets/api/vendor_modules/object-inspect/example/fn.js +5 -0
- package/assets/api/vendor_modules/object-inspect/example/inspect.js +10 -0
- package/assets/api/vendor_modules/object-inspect/index.js +544 -0
- package/assets/api/vendor_modules/object-inspect/package-support.json +20 -0
- package/assets/api/vendor_modules/object-inspect/package.json +105 -0
- package/assets/api/vendor_modules/object-inspect/readme.markdown +84 -0
- package/assets/api/vendor_modules/object-inspect/test/bigint.js +58 -0
- package/assets/api/vendor_modules/object-inspect/test/browser/dom.js +15 -0
- package/assets/api/vendor_modules/object-inspect/test/circular.js +16 -0
- package/assets/api/vendor_modules/object-inspect/test/deep.js +12 -0
- package/assets/api/vendor_modules/object-inspect/test/element.js +53 -0
- package/assets/api/vendor_modules/object-inspect/test/err.js +48 -0
- package/assets/api/vendor_modules/object-inspect/test/fakes.js +29 -0
- package/assets/api/vendor_modules/object-inspect/test/fn.js +76 -0
- package/assets/api/vendor_modules/object-inspect/test/global.js +17 -0
- package/assets/api/vendor_modules/object-inspect/test/has.js +15 -0
- package/assets/api/vendor_modules/object-inspect/test/holes.js +15 -0
- package/assets/api/vendor_modules/object-inspect/test/indent-option.js +271 -0
- package/assets/api/vendor_modules/object-inspect/test/inspect.js +139 -0
- package/assets/api/vendor_modules/object-inspect/test/lowbyte.js +12 -0
- package/assets/api/vendor_modules/object-inspect/test/number.js +58 -0
- package/assets/api/vendor_modules/object-inspect/test/quoteStyle.js +26 -0
- package/assets/api/vendor_modules/object-inspect/test/toStringTag.js +40 -0
- package/assets/api/vendor_modules/object-inspect/test/undef.js +12 -0
- package/assets/api/vendor_modules/object-inspect/test/values.js +261 -0
- package/assets/api/vendor_modules/object-inspect/test-core-js.js +26 -0
- package/assets/api/vendor_modules/object-inspect/util.inspect.js +1 -0
- package/assets/api/vendor_modules/on-finished/HISTORY.md +98 -0
- package/assets/api/vendor_modules/on-finished/LICENSE +23 -0
- package/assets/api/vendor_modules/on-finished/README.md +162 -0
- package/assets/api/vendor_modules/on-finished/index.js +234 -0
- package/assets/api/vendor_modules/on-finished/package.json +39 -0
- package/assets/api/vendor_modules/parseurl/HISTORY.md +58 -0
- package/assets/api/vendor_modules/parseurl/LICENSE +24 -0
- package/assets/api/vendor_modules/parseurl/README.md +133 -0
- package/assets/api/vendor_modules/parseurl/index.js +158 -0
- package/assets/api/vendor_modules/parseurl/package.json +40 -0
- package/assets/api/vendor_modules/path-to-regexp/LICENSE +21 -0
- package/assets/api/vendor_modules/path-to-regexp/Readme.md +35 -0
- package/assets/api/vendor_modules/path-to-regexp/index.js +158 -0
- package/assets/api/vendor_modules/path-to-regexp/package.json +30 -0
- package/assets/api/vendor_modules/proxy-addr/HISTORY.md +167 -0
- package/assets/api/vendor_modules/proxy-addr/LICENSE +22 -0
- package/assets/api/vendor_modules/proxy-addr/README.md +139 -0
- package/assets/api/vendor_modules/proxy-addr/index.js +359 -0
- package/assets/api/vendor_modules/proxy-addr/package.json +51 -0
- package/assets/api/vendor_modules/qs/.editorconfig +46 -0
- package/assets/api/vendor_modules/qs/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/qs/.github/SECURITY.md +11 -0
- package/assets/api/vendor_modules/qs/.github/THREAT_MODEL.md +78 -0
- package/assets/api/vendor_modules/qs/.nycrc +13 -0
- package/assets/api/vendor_modules/qs/CHANGELOG.md +833 -0
- package/assets/api/vendor_modules/qs/LICENSE.md +29 -0
- package/assets/api/vendor_modules/qs/README.md +758 -0
- package/assets/api/vendor_modules/qs/dist/qs.js +141 -0
- package/assets/api/vendor_modules/qs/eslint.config.mjs +57 -0
- package/assets/api/vendor_modules/qs/lib/formats.js +23 -0
- package/assets/api/vendor_modules/qs/lib/index.js +11 -0
- package/assets/api/vendor_modules/qs/lib/parse.js +414 -0
- package/assets/api/vendor_modules/qs/lib/stringify.js +363 -0
- package/assets/api/vendor_modules/qs/lib/utils.js +381 -0
- package/assets/api/vendor_modules/qs/package.json +95 -0
- package/assets/api/vendor_modules/qs/test/empty-keys-cases.js +267 -0
- package/assets/api/vendor_modules/qs/test/parse.js +1933 -0
- package/assets/api/vendor_modules/qs/test/stringify.js +1448 -0
- package/assets/api/vendor_modules/qs/test/utils.js +626 -0
- package/assets/api/vendor_modules/range-parser/HISTORY.md +56 -0
- package/assets/api/vendor_modules/range-parser/LICENSE +23 -0
- package/assets/api/vendor_modules/range-parser/README.md +84 -0
- package/assets/api/vendor_modules/range-parser/index.js +162 -0
- package/assets/api/vendor_modules/range-parser/package.json +44 -0
- package/assets/api/vendor_modules/raw-body/LICENSE +22 -0
- package/assets/api/vendor_modules/raw-body/README.md +223 -0
- package/assets/api/vendor_modules/raw-body/index.d.ts +87 -0
- package/assets/api/vendor_modules/raw-body/index.js +336 -0
- package/assets/api/vendor_modules/raw-body/package.json +47 -0
- package/assets/api/vendor_modules/safe-buffer/LICENSE +21 -0
- package/assets/api/vendor_modules/safe-buffer/README.md +584 -0
- package/assets/api/vendor_modules/safe-buffer/index.d.ts +187 -0
- package/assets/api/vendor_modules/safe-buffer/index.js +65 -0
- package/assets/api/vendor_modules/safe-buffer/package.json +51 -0
- package/assets/api/vendor_modules/safer-buffer/LICENSE +21 -0
- package/assets/api/vendor_modules/safer-buffer/Porting-Buffer.md +268 -0
- package/assets/api/vendor_modules/safer-buffer/Readme.md +156 -0
- package/assets/api/vendor_modules/safer-buffer/dangerous.js +58 -0
- package/assets/api/vendor_modules/safer-buffer/package.json +34 -0
- package/assets/api/vendor_modules/safer-buffer/safer.js +77 -0
- package/assets/api/vendor_modules/safer-buffer/tests.js +406 -0
- package/assets/api/vendor_modules/send/HISTORY.md +538 -0
- package/assets/api/vendor_modules/send/LICENSE +23 -0
- package/assets/api/vendor_modules/send/README.md +327 -0
- package/assets/api/vendor_modules/send/SECURITY.md +24 -0
- package/assets/api/vendor_modules/send/index.js +1142 -0
- package/assets/api/vendor_modules/send/node_modules/ms/index.js +162 -0
- package/assets/api/vendor_modules/send/node_modules/ms/license.md +21 -0
- package/assets/api/vendor_modules/send/node_modules/ms/package.json +38 -0
- package/assets/api/vendor_modules/send/node_modules/ms/readme.md +59 -0
- package/assets/api/vendor_modules/send/package.json +62 -0
- package/assets/api/vendor_modules/serve-static/HISTORY.md +493 -0
- package/assets/api/vendor_modules/serve-static/LICENSE +25 -0
- package/assets/api/vendor_modules/serve-static/README.md +257 -0
- package/assets/api/vendor_modules/serve-static/index.js +209 -0
- package/assets/api/vendor_modules/serve-static/package.json +42 -0
- package/assets/api/vendor_modules/serverless-http/LICENSE.txt +33 -0
- package/assets/api/vendor_modules/serverless-http/README.md +117 -0
- package/assets/api/vendor_modules/serverless-http/lib/finish.js +42 -0
- package/assets/api/vendor_modules/serverless-http/lib/framework/get-framework.js +79 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/aws/clean-up-event.js +98 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/aws/create-request.js +110 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/aws/format-response.js +45 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/aws/index.js +15 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/aws/is-binary.js +42 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/aws/sanitize-headers.js +21 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/clean-up-request.js +41 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/create-request.js +45 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/format-response.js +18 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/index.js +13 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/is-binary.js +42 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/sanitize-headers.js +23 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/azure/set-cookie.json +1 -0
- package/assets/api/vendor_modules/serverless-http/lib/provider/get-provider.js +17 -0
- package/assets/api/vendor_modules/serverless-http/lib/request.js +38 -0
- package/assets/api/vendor_modules/serverless-http/lib/response.js +135 -0
- package/assets/api/vendor_modules/serverless-http/package.json +93 -0
- package/assets/api/vendor_modules/serverless-http/serverless-http.d.ts +41 -0
- package/assets/api/vendor_modules/serverless-http/serverless-http.js +23 -0
- package/assets/api/vendor_modules/setprototypeof/LICENSE +13 -0
- package/assets/api/vendor_modules/setprototypeof/README.md +31 -0
- package/assets/api/vendor_modules/setprototypeof/index.d.ts +2 -0
- package/assets/api/vendor_modules/setprototypeof/index.js +17 -0
- package/assets/api/vendor_modules/setprototypeof/package.json +38 -0
- package/assets/api/vendor_modules/setprototypeof/test/index.js +24 -0
- package/assets/api/vendor_modules/side-channel/.editorconfig +9 -0
- package/assets/api/vendor_modules/side-channel/.eslintrc +12 -0
- package/assets/api/vendor_modules/side-channel/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/side-channel/.nycrc +13 -0
- package/assets/api/vendor_modules/side-channel/CHANGELOG.md +120 -0
- package/assets/api/vendor_modules/side-channel/LICENSE +21 -0
- package/assets/api/vendor_modules/side-channel/README.md +61 -0
- package/assets/api/vendor_modules/side-channel/index.d.ts +14 -0
- package/assets/api/vendor_modules/side-channel/index.js +46 -0
- package/assets/api/vendor_modules/side-channel/package.json +85 -0
- package/assets/api/vendor_modules/side-channel/test/index.js +120 -0
- package/assets/api/vendor_modules/side-channel/tsconfig.json +9 -0
- package/assets/api/vendor_modules/side-channel-list/.editorconfig +9 -0
- package/assets/api/vendor_modules/side-channel-list/.eslintrc +11 -0
- package/assets/api/vendor_modules/side-channel-list/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/side-channel-list/.nycrc +13 -0
- package/assets/api/vendor_modules/side-channel-list/CHANGELOG.md +36 -0
- package/assets/api/vendor_modules/side-channel-list/LICENSE +21 -0
- package/assets/api/vendor_modules/side-channel-list/README.md +62 -0
- package/assets/api/vendor_modules/side-channel-list/index.d.ts +13 -0
- package/assets/api/vendor_modules/side-channel-list/index.js +111 -0
- package/assets/api/vendor_modules/side-channel-list/list.d.ts +14 -0
- package/assets/api/vendor_modules/side-channel-list/package.json +77 -0
- package/assets/api/vendor_modules/side-channel-list/test/index.js +154 -0
- package/assets/api/vendor_modules/side-channel-list/tsconfig.json +9 -0
- package/assets/api/vendor_modules/side-channel-map/.editorconfig +9 -0
- package/assets/api/vendor_modules/side-channel-map/.eslintrc +11 -0
- package/assets/api/vendor_modules/side-channel-map/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/side-channel-map/.nycrc +13 -0
- package/assets/api/vendor_modules/side-channel-map/CHANGELOG.md +22 -0
- package/assets/api/vendor_modules/side-channel-map/LICENSE +21 -0
- package/assets/api/vendor_modules/side-channel-map/README.md +62 -0
- package/assets/api/vendor_modules/side-channel-map/index.d.ts +15 -0
- package/assets/api/vendor_modules/side-channel-map/index.js +68 -0
- package/assets/api/vendor_modules/side-channel-map/package.json +80 -0
- package/assets/api/vendor_modules/side-channel-map/test/index.js +114 -0
- package/assets/api/vendor_modules/side-channel-map/tsconfig.json +9 -0
- package/assets/api/vendor_modules/side-channel-weakmap/.editorconfig +9 -0
- package/assets/api/vendor_modules/side-channel-weakmap/.eslintrc +12 -0
- package/assets/api/vendor_modules/side-channel-weakmap/.github/FUNDING.yml +12 -0
- package/assets/api/vendor_modules/side-channel-weakmap/.nycrc +13 -0
- package/assets/api/vendor_modules/side-channel-weakmap/CHANGELOG.md +28 -0
- package/assets/api/vendor_modules/side-channel-weakmap/LICENSE +21 -0
- package/assets/api/vendor_modules/side-channel-weakmap/README.md +62 -0
- package/assets/api/vendor_modules/side-channel-weakmap/index.d.ts +15 -0
- package/assets/api/vendor_modules/side-channel-weakmap/index.js +84 -0
- package/assets/api/vendor_modules/side-channel-weakmap/package.json +87 -0
- package/assets/api/vendor_modules/side-channel-weakmap/test/index.js +114 -0
- package/assets/api/vendor_modules/side-channel-weakmap/tsconfig.json +9 -0
- package/assets/api/vendor_modules/statuses/HISTORY.md +87 -0
- package/assets/api/vendor_modules/statuses/LICENSE +23 -0
- package/assets/api/vendor_modules/statuses/README.md +139 -0
- package/assets/api/vendor_modules/statuses/codes.json +65 -0
- package/assets/api/vendor_modules/statuses/index.js +146 -0
- package/assets/api/vendor_modules/statuses/package.json +49 -0
- package/assets/api/vendor_modules/toidentifier/HISTORY.md +9 -0
- package/assets/api/vendor_modules/toidentifier/LICENSE +21 -0
- package/assets/api/vendor_modules/toidentifier/README.md +61 -0
- package/assets/api/vendor_modules/toidentifier/index.js +32 -0
- package/assets/api/vendor_modules/toidentifier/package.json +38 -0
- package/assets/api/vendor_modules/type-is/HISTORY.md +259 -0
- package/assets/api/vendor_modules/type-is/LICENSE +23 -0
- package/assets/api/vendor_modules/type-is/README.md +170 -0
- package/assets/api/vendor_modules/type-is/index.js +266 -0
- package/assets/api/vendor_modules/type-is/package.json +45 -0
- package/assets/api/vendor_modules/unpipe/HISTORY.md +4 -0
- package/assets/api/vendor_modules/unpipe/LICENSE +22 -0
- package/assets/api/vendor_modules/unpipe/README.md +43 -0
- package/assets/api/vendor_modules/unpipe/index.js +69 -0
- package/assets/api/vendor_modules/unpipe/package.json +27 -0
- package/assets/api/vendor_modules/utils-merge/LICENSE +20 -0
- package/assets/api/vendor_modules/utils-merge/README.md +34 -0
- package/assets/api/vendor_modules/utils-merge/index.js +23 -0
- package/assets/api/vendor_modules/utils-merge/package.json +40 -0
- package/assets/api/vendor_modules/vary/HISTORY.md +39 -0
- package/assets/api/vendor_modules/vary/LICENSE +22 -0
- package/assets/api/vendor_modules/vary/README.md +101 -0
- package/assets/api/vendor_modules/vary/index.js +149 -0
- package/assets/api/vendor_modules/vary/package.json +43 -0
- package/assets/federation-presignup/index.js +108 -0
- package/assets/firstadmin/index.js +361 -0
- package/assets/headscale-apikey/index.js +140 -0
- package/assets/invoke-relay/index.js +96 -0
- package/assets/issuer-canary/index.js +71 -0
- package/assets/issuer-publish/index.js +87 -0
- package/assets/keyminter/index.js +209 -0
- package/assets/plugin-authorizer/index.js +1740 -0
- package/assets/plugin-catalog/index.js +881 -0
- package/assets/reapproval/index.js +3761 -0
- package/assets/sg-manager/index.js +176 -0
- package/assets/tailnet-resolver/index.js +55 -0
- package/assets/web/chunk-2MOGDYK4.js +1 -0
- package/assets/web/chunk-2SO4BVIT.js +1 -0
- package/assets/web/chunk-2V6RSAAC.js +1 -0
- package/assets/web/chunk-32GNBTAL.js +1 -0
- package/assets/web/chunk-33SYY2JB.js +1 -0
- package/assets/web/chunk-3VWYT7AX.js +1 -0
- package/assets/web/chunk-4FG4DAWU.js +4 -0
- package/assets/web/chunk-4N2IUS6T.js +1 -0
- package/assets/web/chunk-4SK6XQ6C.js +1 -0
- package/assets/web/chunk-65WE5MXA.js +8 -0
- package/assets/web/chunk-6D7SSSJF.js +1 -0
- package/assets/web/chunk-6KFR7DYY.js +1 -0
- package/assets/web/chunk-A4WHI3ZG.js +8 -0
- package/assets/web/chunk-BNFKRZTP.js +1 -0
- package/assets/web/chunk-CG56PH3M.js +1 -0
- package/assets/web/chunk-CGO25AIM.js +1 -0
- package/assets/web/chunk-CP4XZPOA.js +1 -0
- package/assets/web/chunk-CV7EODPO.js +1 -0
- package/assets/web/chunk-D7TR2ORJ.js +1 -0
- package/assets/web/chunk-DCOFBAKJ.js +1 -0
- package/assets/web/chunk-DOLRLYW7.js +1 -0
- package/assets/web/chunk-EEJ3X466.js +1 -0
- package/assets/web/chunk-EQ4PF25J.js +1 -0
- package/assets/web/chunk-EVP5UVDQ.js +1 -0
- package/assets/web/chunk-EW2VMNHE.js +1 -0
- package/assets/web/chunk-FIUVIKAN.js +1 -0
- package/assets/web/chunk-GHEU25TG.js +1 -0
- package/assets/web/chunk-GK2T2SMO.js +1 -0
- package/assets/web/chunk-GKI3R2JB.js +1 -0
- package/assets/web/chunk-GPKKIOHD.js +2 -0
- package/assets/web/chunk-H4AVFUDM.js +1 -0
- package/assets/web/chunk-H5H727H6.js +1 -0
- package/assets/web/chunk-HGVFH6YM.js +1 -0
- package/assets/web/chunk-HHPIANBK.js +1 -0
- package/assets/web/chunk-HK56COCB.js +1 -0
- package/assets/web/chunk-HZUB7LFV.js +1 -0
- package/assets/web/chunk-I7NTNTBA.js +1 -0
- package/assets/web/chunk-IKK5DQ3Z.js +1 -0
- package/assets/web/chunk-IMH56UBX.js +1 -0
- package/assets/web/chunk-J3SSPCFV.js +1 -0
- package/assets/web/chunk-J4C7C5KO.js +1 -0
- package/assets/web/chunk-J57JB4MU.js +1 -0
- package/assets/web/chunk-JMBXRK3I.js +4 -0
- package/assets/web/chunk-KCCEQIXX.js +1 -0
- package/assets/web/chunk-KEBESIXR.js +1 -0
- package/assets/web/chunk-KPNHT4MK.js +1 -0
- package/assets/web/chunk-LMLXTVZG.js +1 -0
- package/assets/web/chunk-M6OAYNRE.js +1 -0
- package/assets/web/chunk-M7MGX5I4.js +1 -0
- package/assets/web/chunk-MU2VNTNY.js +1 -0
- package/assets/web/chunk-NABAVDRL.js +1 -0
- package/assets/web/chunk-NO5D6WDF.js +1 -0
- package/assets/web/chunk-O4QSFUXB.js +1 -0
- package/assets/web/chunk-OATVFQXO.js +1 -0
- package/assets/web/chunk-P5WRM37W.js +5 -0
- package/assets/web/chunk-PCP6D2SM.js +1 -0
- package/assets/web/chunk-PMMBJK7Q.js +1 -0
- package/assets/web/chunk-PSMER3HX.js +1 -0
- package/assets/web/chunk-QPBWZLCT.js +1 -0
- package/assets/web/chunk-QVABVDO5.js +1 -0
- package/assets/web/chunk-RI77LE5V.js +1 -0
- package/assets/web/chunk-RKGUEXZ2.js +1 -0
- package/assets/web/chunk-RMFH2YTZ.js +1 -0
- package/assets/web/chunk-RROPCBUH.js +1 -0
- package/assets/web/chunk-SJMLX5AT.js +1 -0
- package/assets/web/chunk-TKVALOE4.js +2 -0
- package/assets/web/chunk-TM43WUKM.js +1 -0
- package/assets/web/chunk-VKWV3ANT.js +1 -0
- package/assets/web/chunk-VTMYG6YW.js +1 -0
- package/assets/web/chunk-VWW4SA5R.js +1 -0
- package/assets/web/chunk-WEDAFMID.js +1 -0
- package/assets/web/chunk-WFIHWVQO.js +1 -0
- package/assets/web/chunk-XJM3HDJQ.js +1 -0
- package/assets/web/chunk-YVJV2RUY.js +1 -0
- package/assets/web/chunk-Z3KONI7L.js +1 -0
- package/assets/web/chunk-ZDCURXPS.js +1 -0
- package/assets/web/favicon.ico +0 -0
- package/assets/web/index.html +63 -0
- package/assets/web/main-S6E3BC5O.js +2 -0
- package/assets/web/polyfills-7RSNIJ6J.js +2 -0
- package/assets/web/styles-R6ZUWC6K.css +1 -0
- package/dist/index.d.ts +27 -0
- package/dist/index.js +66 -0
- package/dist/lambdacode/api/services/brandingShapes.d.ts +5 -0
- package/dist/lambdacode/api/services/brandingShapes.js +15 -0
- package/dist/lambdacode/issuer/objects.d.ts +8 -0
- package/dist/lambdacode/issuer/objects.js +11 -0
- package/dist/lambdacode/network/naming.d.ts +52 -0
- package/dist/lambdacode/network/naming.js +67 -0
- package/dist/lib/access-portal-hub.d.ts +53 -0
- package/dist/lib/access-portal-hub.js +87 -0
- package/dist/lib/access-portal.d.ts +32 -0
- package/dist/lib/access-portal.js +174 -0
- package/dist/lib/audit-log.d.ts +18 -0
- package/dist/lib/audit-log.js +25 -0
- package/dist/lib/connector-stack.d.ts +28 -0
- package/dist/lib/connector-stack.js +81 -0
- package/dist/lib/constructs/app-function.d.ts +14 -0
- package/dist/lib/constructs/app-function.js +84 -0
- package/dist/lib/constructs/app-table.d.ts +12 -0
- package/dist/lib/constructs/app-table.js +58 -0
- package/dist/lib/constructs/mirrored-image.d.ts +12 -0
- package/dist/lib/constructs/mirrored-image.js +80 -0
- package/dist/lib/constructs/monitoring.d.ts +21 -0
- package/dist/lib/constructs/monitoring.js +133 -0
- package/dist/lib/constructs/oidc-issuer.d.ts +44 -0
- package/dist/lib/constructs/oidc-issuer.js +234 -0
- package/dist/lib/constructs/scratch-tmpfs.d.ts +5 -0
- package/dist/lib/constructs/scratch-tmpfs.js +48 -0
- package/dist/lib/constructs/sg-manager.d.ts +27 -0
- package/dist/lib/constructs/sg-manager.js +88 -0
- package/dist/lib/constructs/tailnet-connector.d.ts +29 -0
- package/dist/lib/constructs/tailnet-connector.js +177 -0
- package/dist/lib/constructs/tailnet-resolver.d.ts +30 -0
- package/dist/lib/constructs/tailnet-resolver.js +71 -0
- package/dist/lib/constructs/target-account-trust.d.ts +32 -0
- package/dist/lib/constructs/target-account-trust.js +81 -0
- package/dist/lib/constructs/vending-api.d.ts +103 -0
- package/dist/lib/constructs/vending-api.js +203 -0
- package/dist/lib/constructs/web-acl.d.ts +61 -0
- package/dist/lib/constructs/web-acl.js +213 -0
- package/dist/lib/constructs/web-identity.d.ts +49 -0
- package/dist/lib/constructs/web-identity.js +116 -0
- package/dist/lib/creds-stack.d.ts +151 -0
- package/dist/lib/creds-stack.js +592 -0
- package/dist/lib/data-stack.d.ts +53 -0
- package/dist/lib/data-stack.js +282 -0
- package/dist/lib/dimensions-validation.d.ts +20 -0
- package/dist/lib/dimensions-validation.js +51 -0
- package/dist/lib/federation.d.ts +113 -0
- package/dist/lib/federation.js +254 -0
- package/dist/lib/managed-login-branding.json +450 -0
- package/dist/lib/network-stack.d.ts +58 -0
- package/dist/lib/network-stack.js +776 -0
- package/dist/lib/network-validation.d.ts +54 -0
- package/dist/lib/network-validation.js +220 -0
- package/dist/lib/pkg-paths.d.ts +3 -0
- package/dist/lib/pkg-paths.js +51 -0
- package/dist/lib/plugins/plugin-api.d.ts +40 -0
- package/dist/lib/plugins/plugin-api.js +125 -0
- package/dist/lib/plugins/plugin-catalog-activation.d.ts +31 -0
- package/dist/lib/plugins/plugin-catalog-activation.js +109 -0
- package/dist/lib/plugins/registration.d.ts +41 -0
- package/dist/lib/plugins/registration.js +121 -0
- package/dist/lib/plugins/runtime.d.ts +10 -0
- package/dist/lib/plugins/runtime.js +17 -0
- package/dist/lib/project-config.d.ts +164 -0
- package/dist/lib/project-config.js +2 -0
- package/dist/lib/target-account-stack.d.ts +15 -0
- package/dist/lib/target-account-stack.js +59 -0
- package/dist/lib/target-account-template.d.ts +13 -0
- package/dist/lib/target-account-template.js +64 -0
- package/dist/lib/web-cert-stack.d.ts +30 -0
- package/dist/lib/web-cert-stack.js +90 -0
- package/dist/lib/web-stack.d.ts +103 -0
- package/dist/lib/web-stack.js +540 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/README.md +303 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/backend/context.d.ts +31 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/backend/context.js +58 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/backend/index.d.ts +9 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/backend/index.js +26 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/client.d.ts +59 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/client.js +290 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/errors.d.ts +14 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/errors.js +32 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/http.d.ts +72 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/http.js +170 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/index.d.ts +11 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/index.js +28 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/theme-apply.d.ts +22 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/browser/theme-apply.js +22 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/access.d.ts +14 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/access.js +41 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/authorizer.d.ts +17 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/authorizer.js +44 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/canonical.d.ts +2 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/canonical.js +21 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/catalog.d.ts +39 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/catalog.js +18 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/discovery.d.ts +78 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/discovery.js +48 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/fields.d.ts +7 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/fields.js +2 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/manifest.d.ts +59 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/manifest.js +19 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/messages.d.ts +111 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/messages.js +109 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/paths.d.ts +20 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/paths.js +49 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/theme.d.ts +21 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/theme.js +60 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/transport.d.ts +14 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/transport.js +10 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/validate.d.ts +27 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/contracts/validate.js +321 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/devHost.d.ts +61 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/devHost.js +99 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/fakeDocument.d.ts +12 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/fakeDocument.js +22 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/fakeWindows.d.ts +22 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/fakeWindows.js +46 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/index.d.ts +4 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/index.js +20 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/samples.d.ts +37 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/fixtures/samples.js +228 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/host/host.d.ts +47 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/host/host.js +121 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/host/index.d.ts +5 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/host/index.js +22 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/index.d.ts +10 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/dist/index.js +28 -0
- package/node_modules/@fntio/infra-client-plugin-sdk/package.json +99 -0
- package/openapi.yaml +4284 -0
- package/package.json +124 -4
package/openapi.yaml
ADDED
|
@@ -0,0 +1,4284 @@
|
|
|
1
|
+
# The HTTP contract of the portal API — every route the Express app mounts.
|
|
2
|
+
# lambdacode/api/__tests__/openapi.test.ts fails when a mounted route is
|
|
3
|
+
# missing here (or a documented one is gone), so this file cannot go stale.
|
|
4
|
+
# The private dev repo generates its Postman collection FROM this file.
|
|
5
|
+
openapi: 3.1.0
|
|
6
|
+
info:
|
|
7
|
+
title: Infra Client API
|
|
8
|
+
version: 0.5.0
|
|
9
|
+
summary: Self-hosted AWS access portal — credential vending, access requests, admin catalog, private-network resources.
|
|
10
|
+
description: |
|
|
11
|
+
One Express app behind CloudFront (`/api/*`) and API Gateway (no prefix).
|
|
12
|
+
|
|
13
|
+
## Authentication
|
|
14
|
+
|
|
15
|
+
Every route except `GET /health` and `GET /.well-known/infra-client` takes
|
|
16
|
+
`Authorization: Bearer <token>`, where the token is one of:
|
|
17
|
+
|
|
18
|
+
- **Human** — a Cognito **ID token** from the portal's user pool (in-app sign-in).
|
|
19
|
+
Admin routes additionally require membership of the `admins` group
|
|
20
|
+
(`cognito:groups` claim).
|
|
21
|
+
- **Service user** — a Cognito **access token** minted with the
|
|
22
|
+
`client_credentials` grant by an app client an admin created under
|
|
23
|
+
*Admin → Service users*. It carries the `api/invoke` scope; its `sub` is
|
|
24
|
+
the client id. **Every service user is an app admin**, so it may call
|
|
25
|
+
every route below — including `POST /credentials` to vend AWS credentials
|
|
26
|
+
for the roles granted to it.
|
|
27
|
+
|
|
28
|
+
Token exchange for service users (see the Access Model wiki page, "Service users"):
|
|
29
|
+
|
|
30
|
+
POST https://<cognito domain>/oauth2/token
|
|
31
|
+
Authorization: Basic base64(clientId:clientSecret)
|
|
32
|
+
Content-Type: application/x-www-form-urlencoded
|
|
33
|
+
|
|
34
|
+
grant_type=client_credentials&scope=api/invoke
|
|
35
|
+
|
|
36
|
+
## Conventions
|
|
37
|
+
|
|
38
|
+
- Errors are always JSON `{ "message": "…" }`. `401` = no/invalid token,
|
|
39
|
+
`403` = not an admin (or no grant on a vend), `404` = addressed thing
|
|
40
|
+
missing, `409` = already exists / still in use / already decided,
|
|
41
|
+
`400` = malformed input, `501` = feature not deployed (private network,
|
|
42
|
+
branding storage), `502` = a downstream AWS call failed.
|
|
43
|
+
- Timestamps are ISO-8601 strings in UTC.
|
|
44
|
+
- `accountNumber` is always the 12-digit AWS account id.
|
|
45
|
+
- `userId` is the Cognito `sub` for humans and the app client id for
|
|
46
|
+
service users — both are valid grant principals everywhere a `userId`
|
|
47
|
+
path parameter appears.
|
|
48
|
+
- Lists are returned whole; there is no server-side paging.
|
|
49
|
+
- Temporary access uses the duration presets `1, 12, 24, 72, 168, 720`
|
|
50
|
+
hours (1 h … 30 d). Omitting the duration means long-term (standing) access.
|
|
51
|
+
license:
|
|
52
|
+
name: Elastic License 2.0
|
|
53
|
+
identifier: Elastic-2.0
|
|
54
|
+
servers:
|
|
55
|
+
- url: https://{host}/api
|
|
56
|
+
description: Through the portal's CloudFront distribution (the web domain in your project config).
|
|
57
|
+
variables:
|
|
58
|
+
host:
|
|
59
|
+
default: portal.example.com
|
|
60
|
+
description: Your deployment's web domain.
|
|
61
|
+
security:
|
|
62
|
+
- bearerAuth: []
|
|
63
|
+
tags:
|
|
64
|
+
- name: Health
|
|
65
|
+
description: Liveness and the public discovery document.
|
|
66
|
+
- name: Access
|
|
67
|
+
description: What the caller may assume, and vending credentials or a console sign-in for it.
|
|
68
|
+
- name: Requests
|
|
69
|
+
description: The caller's own access requests (raising, listing, acknowledging decisions).
|
|
70
|
+
- name: Preferences
|
|
71
|
+
description: The caller's per-role and network preferences.
|
|
72
|
+
- name: Network
|
|
73
|
+
description: Private-network (VPN) sites and device enrollment.
|
|
74
|
+
- name: Resources
|
|
75
|
+
description: Private-network resources the caller can reach.
|
|
76
|
+
- name: Notifications
|
|
77
|
+
description: The caller's revoked-access notices (the bell).
|
|
78
|
+
- name: "Admin: setup"
|
|
79
|
+
description: First-run checklist state and branding.
|
|
80
|
+
- name: "Admin: accounts & roles"
|
|
81
|
+
description: The catalog of AWS accounts and the roles registered in them.
|
|
82
|
+
- name: "Admin: grants"
|
|
83
|
+
description: Who holds which role, directly or via groups.
|
|
84
|
+
- name: "Admin: users"
|
|
85
|
+
description: The Cognito directory and per-user cascades.
|
|
86
|
+
- name: "Admin: service users"
|
|
87
|
+
description: Machine-to-machine app clients (client_credentials).
|
|
88
|
+
- name: "Admin: groups"
|
|
89
|
+
description: Role/resource bundles whose members inherit the bundle.
|
|
90
|
+
- name: "Admin: requests"
|
|
91
|
+
description: The approval queue and history.
|
|
92
|
+
- name: "Admin: resources"
|
|
93
|
+
description: Private-network resource catalog and resource grants.
|
|
94
|
+
- name: "Admin: network"
|
|
95
|
+
description: Site topology and the grants→ACL reconciler.
|
|
96
|
+
- name: "Admin: audit"
|
|
97
|
+
description: The vend / console / device-key event log.
|
|
98
|
+
- name: Plugins
|
|
99
|
+
description: What the signed-in caller may open, for the portal's own navigation.
|
|
100
|
+
- name: "Admin: plugins"
|
|
101
|
+
description: Every installed plugin definition, and who may use each binding.
|
|
102
|
+
|
|
103
|
+
paths:
|
|
104
|
+
/health:
|
|
105
|
+
get:
|
|
106
|
+
tags: [Health]
|
|
107
|
+
summary: Liveness
|
|
108
|
+
operationId: health
|
|
109
|
+
security: []
|
|
110
|
+
responses:
|
|
111
|
+
"200":
|
|
112
|
+
description: The API is up.
|
|
113
|
+
content:
|
|
114
|
+
application/json:
|
|
115
|
+
schema:
|
|
116
|
+
type: object
|
|
117
|
+
properties:
|
|
118
|
+
ok: { type: boolean, const: true }
|
|
119
|
+
required: [ok]
|
|
120
|
+
|
|
121
|
+
/.well-known/infra-client:
|
|
122
|
+
get:
|
|
123
|
+
tags: [Health]
|
|
124
|
+
summary: Discovery document (public)
|
|
125
|
+
operationId: discovery
|
|
126
|
+
description: |
|
|
127
|
+
What the desktop app reads to self-configure from a deployment URL:
|
|
128
|
+
the project name, the Cognito pool/client ids the SPA already ships
|
|
129
|
+
with, the OIDC issuer, and the VPN control planes. Never secrets.
|
|
130
|
+
security: []
|
|
131
|
+
responses:
|
|
132
|
+
"200":
|
|
133
|
+
description: Discovery document.
|
|
134
|
+
content:
|
|
135
|
+
application/json:
|
|
136
|
+
schema: { $ref: "#/components/schemas/Discovery" }
|
|
137
|
+
|
|
138
|
+
/accounts:
|
|
139
|
+
get:
|
|
140
|
+
tags: [Access]
|
|
141
|
+
summary: List my access
|
|
142
|
+
operationId: listAccess
|
|
143
|
+
description: |
|
|
144
|
+
Accounts and roles the caller may assume right now (direct and group-provided grants, expired ones excluded), each with its resolved `~/.aws` profile name.
|
|
145
|
+
With `limit`, one page of the list contract: sorts `position` (the admin order, default), `name`, `number`; facets `environment`, `main` (`true`/`false` — whether the account sits in the dashboard's Main section), `favorite` (`true`/`false` — the caller's own favorites), plus `tenant`, `project`, `stage` on a deployment with account dimensions (`unclassified` for an account without one).
|
|
146
|
+
Each account carries `main: false` only when an admin took it off the Main section.
|
|
147
|
+
parameters:
|
|
148
|
+
- $ref: "#/components/parameters/listQ"
|
|
149
|
+
- $ref: "#/components/parameters/listFilter"
|
|
150
|
+
- $ref: "#/components/parameters/listSort"
|
|
151
|
+
- $ref: "#/components/parameters/listLimit"
|
|
152
|
+
- $ref: "#/components/parameters/listCursor"
|
|
153
|
+
responses:
|
|
154
|
+
"200":
|
|
155
|
+
description: The caller's accounts — the whole list, or one page when `limit` was passed.
|
|
156
|
+
content:
|
|
157
|
+
application/json:
|
|
158
|
+
schema:
|
|
159
|
+
oneOf:
|
|
160
|
+
- type: object
|
|
161
|
+
properties:
|
|
162
|
+
accounts:
|
|
163
|
+
type: array
|
|
164
|
+
items: { $ref: "#/components/schemas/AccountAccess" }
|
|
165
|
+
required: [accounts]
|
|
166
|
+
- $ref: "#/components/schemas/AccountAccessPage"
|
|
167
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
168
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
169
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
170
|
+
|
|
171
|
+
/accounts/home:
|
|
172
|
+
get:
|
|
173
|
+
tags: [Access]
|
|
174
|
+
summary: My dashboard
|
|
175
|
+
operationId: homeAccess
|
|
176
|
+
description: |
|
|
177
|
+
The caller's access cut into the dashboard's shortcuts. `sectioned` is true once the caller holds an account
|
|
178
|
+
that is not main (or whenever `layout` is `sections`); until then `main` is the whole list and the dashboard
|
|
179
|
+
shows no sections. A caller who holds nothing is never sectioned, whatever the layout. Accounts the caller
|
|
180
|
+
holds nothing in are not listed: asking for one is `GET /requests/catalog`'s job.
|
|
181
|
+
responses:
|
|
182
|
+
"200":
|
|
183
|
+
description: The dashboard.
|
|
184
|
+
content:
|
|
185
|
+
application/json:
|
|
186
|
+
schema:
|
|
187
|
+
type: object
|
|
188
|
+
properties:
|
|
189
|
+
sectioned: { type: boolean }
|
|
190
|
+
heldTotal: { type: integer, minimum: 0 }
|
|
191
|
+
main: { type: array, items: { $ref: "#/components/schemas/AccountAccess" } }
|
|
192
|
+
favorites: { type: array, items: { $ref: "#/components/schemas/AccountAccess" } }
|
|
193
|
+
recent: { type: array, items: { $ref: "#/components/schemas/AccountAccess" }, description: Newest first. }
|
|
194
|
+
favoriteNumbers: { type: array, items: { $ref: "#/components/schemas/AccountNumber" } }
|
|
195
|
+
layout: { type: string, enum: [auto, sections, plain], description: The deployment-wide setting behind `sectioned` (`PUT /admin/dashboard-layout`). }
|
|
196
|
+
required: [sectioned, heldTotal, main, favorites, recent, favoriteNumbers, layout]
|
|
197
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
198
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
199
|
+
|
|
200
|
+
/accounts/names:
|
|
201
|
+
get:
|
|
202
|
+
tags: [Access]
|
|
203
|
+
summary: Friendly names of every registered account
|
|
204
|
+
operationId: listAccountNames
|
|
205
|
+
description: |
|
|
206
|
+
Account number → admin-set name, for every registered account that has one — the label lookup the web app
|
|
207
|
+
binds on chips and rows. Catalog facts only, never roles or holders; a few dozen KB where the full catalog is
|
|
208
|
+
megabytes. Every signed-in user may read it (the request catalog already shows every account).
|
|
209
|
+
responses:
|
|
210
|
+
"200":
|
|
211
|
+
description: The name map.
|
|
212
|
+
content:
|
|
213
|
+
application/json:
|
|
214
|
+
schema:
|
|
215
|
+
type: object
|
|
216
|
+
properties:
|
|
217
|
+
names:
|
|
218
|
+
type: object
|
|
219
|
+
additionalProperties: { type: string }
|
|
220
|
+
required: [names]
|
|
221
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
222
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
223
|
+
/accounts/expiry:
|
|
224
|
+
get:
|
|
225
|
+
tags: [Access]
|
|
226
|
+
summary: My expiry notices
|
|
227
|
+
operationId: listExpiryNotices
|
|
228
|
+
description: The caller's temporary role grants nearing (`expiring`) or past (`expired`) their end — the bell feed.
|
|
229
|
+
responses:
|
|
230
|
+
"200":
|
|
231
|
+
description: Expiry notices by phase.
|
|
232
|
+
content:
|
|
233
|
+
application/json:
|
|
234
|
+
schema: { $ref: "#/components/schemas/ExpiryNotices" }
|
|
235
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
236
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
237
|
+
|
|
238
|
+
/accounts/expiry/seen:
|
|
239
|
+
post:
|
|
240
|
+
tags: [Access]
|
|
241
|
+
summary: Acknowledge expiry notices
|
|
242
|
+
operationId: markExpiryNoticesSeen
|
|
243
|
+
responses:
|
|
244
|
+
"200":
|
|
245
|
+
description: How many notices were newly marked seen.
|
|
246
|
+
content:
|
|
247
|
+
application/json:
|
|
248
|
+
schema: { $ref: "#/components/schemas/Cleared" }
|
|
249
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
250
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
251
|
+
|
|
252
|
+
/accounts/{accountNumber}/roles/{roleName}/console:
|
|
253
|
+
post:
|
|
254
|
+
tags: [Access]
|
|
255
|
+
summary: Console sign-in URL
|
|
256
|
+
operationId: consoleSignIn
|
|
257
|
+
description: |
|
|
258
|
+
"Go to Console": same grant check as `POST /credentials`, returns a
|
|
259
|
+
short-lived AWS console federation URL. Every call — vended, denied or
|
|
260
|
+
failed — writes an audit event.
|
|
261
|
+
parameters:
|
|
262
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
263
|
+
- $ref: "#/components/parameters/roleName"
|
|
264
|
+
requestBody:
|
|
265
|
+
content:
|
|
266
|
+
application/json:
|
|
267
|
+
schema:
|
|
268
|
+
type: object
|
|
269
|
+
properties:
|
|
270
|
+
destination:
|
|
271
|
+
type: string
|
|
272
|
+
format: uri
|
|
273
|
+
description: Optional post-login destination; must be an `https://…console.aws.amazon.com/` URL.
|
|
274
|
+
example: { destination: "https://eu-central-1.console.aws.amazon.com/s3/home" }
|
|
275
|
+
responses:
|
|
276
|
+
"200":
|
|
277
|
+
description: The sign-in URL.
|
|
278
|
+
content:
|
|
279
|
+
application/json:
|
|
280
|
+
schema: { $ref: "#/components/schemas/ConsoleSignIn" }
|
|
281
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
282
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
283
|
+
"403":
|
|
284
|
+
description: No active grant for this role (`NO_GRANT` or `EXPIRED`), or the role is no longer in the catalog (`NO_ROLE`).
|
|
285
|
+
content:
|
|
286
|
+
application/json:
|
|
287
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
288
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
289
|
+
|
|
290
|
+
/credentials:
|
|
291
|
+
post:
|
|
292
|
+
tags: [Access]
|
|
293
|
+
summary: Vend credentials
|
|
294
|
+
operationId: vendCredentials
|
|
295
|
+
description: |
|
|
296
|
+
Temporary AWS credentials for a role the caller holds. The session
|
|
297
|
+
length is the role's `sessionDurationSeconds` (default 3600), capped
|
|
298
|
+
by the IAM role's MaxSessionDuration — a cap violation is a `502`
|
|
299
|
+
whose message says so. Every call writes an audit event.
|
|
300
|
+
requestBody:
|
|
301
|
+
required: true
|
|
302
|
+
content:
|
|
303
|
+
application/json:
|
|
304
|
+
schema:
|
|
305
|
+
type: object
|
|
306
|
+
properties:
|
|
307
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
308
|
+
role:
|
|
309
|
+
type: string
|
|
310
|
+
maxLength: 128
|
|
311
|
+
description: The role name (not the ARN). May not contain `#` or `/`.
|
|
312
|
+
background:
|
|
313
|
+
type: boolean
|
|
314
|
+
description: "true = an automatic renewal (desktop keep-fresh), which does not count as the person reaching for the account: it leaves the dashboard's Recent section alone."
|
|
315
|
+
required: [accountNumber, role]
|
|
316
|
+
example: { accountNumber: "123456789012", role: "ReadOnly" }
|
|
317
|
+
responses:
|
|
318
|
+
"200":
|
|
319
|
+
description: Credentials.
|
|
320
|
+
content:
|
|
321
|
+
application/json:
|
|
322
|
+
schema: { $ref: "#/components/schemas/VendedCredentials" }
|
|
323
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
324
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
325
|
+
"403":
|
|
326
|
+
description: No active grant for this role (`NO_GRANT` or `EXPIRED`), or the role is no longer in the catalog (`NO_ROLE`).
|
|
327
|
+
content:
|
|
328
|
+
application/json:
|
|
329
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
330
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
331
|
+
|
|
332
|
+
/requests/catalog:
|
|
333
|
+
get:
|
|
334
|
+
tags: [Requests]
|
|
335
|
+
summary: Requestable roles
|
|
336
|
+
operationId: listRequestableRoles
|
|
337
|
+
description: |
|
|
338
|
+
The role catalog minus what the caller already holds long-term or has pending. Account numbers and role names only — never ARNs or holders.
|
|
339
|
+
With `limit`, one page of the list contract: sorts `name` (default), `number`; facets `tenant`, `project`, `stage` on a deployment with account dimensions (`unclassified` for an account without one), none otherwise.
|
|
340
|
+
parameters:
|
|
341
|
+
- $ref: "#/components/parameters/listQ"
|
|
342
|
+
- $ref: "#/components/parameters/listFilter"
|
|
343
|
+
- $ref: "#/components/parameters/listSort"
|
|
344
|
+
- $ref: "#/components/parameters/listLimit"
|
|
345
|
+
- $ref: "#/components/parameters/listCursor"
|
|
346
|
+
responses:
|
|
347
|
+
"200":
|
|
348
|
+
description: Accounts with requestable roles — the whole list, or one page when `limit` was passed.
|
|
349
|
+
content:
|
|
350
|
+
application/json:
|
|
351
|
+
schema:
|
|
352
|
+
oneOf:
|
|
353
|
+
- type: object
|
|
354
|
+
properties:
|
|
355
|
+
accounts:
|
|
356
|
+
type: array
|
|
357
|
+
items: { $ref: "#/components/schemas/RequestableAccount" }
|
|
358
|
+
required: [accounts]
|
|
359
|
+
- $ref: "#/components/schemas/RequestableAccountPage"
|
|
360
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
361
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
362
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
363
|
+
|
|
364
|
+
/requests/resource-catalog:
|
|
365
|
+
get:
|
|
366
|
+
tags: [Requests]
|
|
367
|
+
summary: Requestable resources
|
|
368
|
+
operationId: listRequestableResources
|
|
369
|
+
description: Private-network resources the caller may ask for — name, type, description and account only; connection details appear only after a grant (`GET /resources`).
|
|
370
|
+
responses:
|
|
371
|
+
"200":
|
|
372
|
+
description: Requestable resources.
|
|
373
|
+
content:
|
|
374
|
+
application/json:
|
|
375
|
+
schema:
|
|
376
|
+
type: object
|
|
377
|
+
properties:
|
|
378
|
+
resources:
|
|
379
|
+
type: array
|
|
380
|
+
items: { $ref: "#/components/schemas/RequestableResource" }
|
|
381
|
+
required: [resources]
|
|
382
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
383
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
384
|
+
|
|
385
|
+
/requests:
|
|
386
|
+
get:
|
|
387
|
+
tags: [Requests]
|
|
388
|
+
summary: My requests
|
|
389
|
+
operationId: listMyRequests
|
|
390
|
+
description: The caller's own requests, newest first. Resource rows carry a resolved `resourceName`.
|
|
391
|
+
responses:
|
|
392
|
+
"200":
|
|
393
|
+
description: The caller's requests.
|
|
394
|
+
content:
|
|
395
|
+
application/json:
|
|
396
|
+
schema:
|
|
397
|
+
type: object
|
|
398
|
+
properties:
|
|
399
|
+
requests:
|
|
400
|
+
type: array
|
|
401
|
+
items: { $ref: "#/components/schemas/AccessRequest" }
|
|
402
|
+
required: [requests]
|
|
403
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
404
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
405
|
+
post:
|
|
406
|
+
tags: [Requests]
|
|
407
|
+
summary: Request a role
|
|
408
|
+
operationId: createRequest
|
|
409
|
+
description: Ask for a role. The requester is always the caller. `409` if the caller already holds it long-term or has one pending; `404` if the role is not catalogued.
|
|
410
|
+
requestBody:
|
|
411
|
+
required: true
|
|
412
|
+
content:
|
|
413
|
+
application/json:
|
|
414
|
+
schema:
|
|
415
|
+
type: object
|
|
416
|
+
properties:
|
|
417
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
418
|
+
roleName: { type: string }
|
|
419
|
+
reason: { type: string, maxLength: 500 }
|
|
420
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
421
|
+
required: [accountNumber, roleName]
|
|
422
|
+
example: { accountNumber: "123456789012", roleName: "ReadOnly", reason: "Investigating an incident", durationHours: 24 }
|
|
423
|
+
responses:
|
|
424
|
+
"201":
|
|
425
|
+
description: The pending request.
|
|
426
|
+
content:
|
|
427
|
+
application/json:
|
|
428
|
+
schema: { $ref: "#/components/schemas/RequestEnvelope" }
|
|
429
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
430
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
431
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
432
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
433
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
434
|
+
|
|
435
|
+
/requests/resource:
|
|
436
|
+
post:
|
|
437
|
+
tags: [Requests]
|
|
438
|
+
summary: Request a resource
|
|
439
|
+
operationId: createResourceRequest
|
|
440
|
+
description: Ask for private-network access to one resource. Same rules as requesting a role.
|
|
441
|
+
requestBody:
|
|
442
|
+
required: true
|
|
443
|
+
content:
|
|
444
|
+
application/json:
|
|
445
|
+
schema:
|
|
446
|
+
type: object
|
|
447
|
+
properties:
|
|
448
|
+
resourceId: { type: string }
|
|
449
|
+
reason: { type: string, maxLength: 500 }
|
|
450
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
451
|
+
required: [resourceId]
|
|
452
|
+
example: { resourceId: "7f1c2b3a-0000-4000-8000-000000000000", reason: "Need the staging database", durationHours: 72 }
|
|
453
|
+
responses:
|
|
454
|
+
"201":
|
|
455
|
+
description: The pending request.
|
|
456
|
+
content:
|
|
457
|
+
application/json:
|
|
458
|
+
schema: { $ref: "#/components/schemas/RequestEnvelope" }
|
|
459
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
460
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
461
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
462
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
463
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
464
|
+
|
|
465
|
+
/requests/seen:
|
|
466
|
+
post:
|
|
467
|
+
tags: [Requests]
|
|
468
|
+
summary: Acknowledge decisions
|
|
469
|
+
operationId: markRequestsSeen
|
|
470
|
+
description: Marks the caller's decided requests as seen (clears the bell badge).
|
|
471
|
+
responses:
|
|
472
|
+
"200":
|
|
473
|
+
description: How many requests were newly marked seen.
|
|
474
|
+
content:
|
|
475
|
+
application/json:
|
|
476
|
+
schema: { $ref: "#/components/schemas/Cleared" }
|
|
477
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
478
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
479
|
+
|
|
480
|
+
/preferences:
|
|
481
|
+
get:
|
|
482
|
+
tags: [Preferences]
|
|
483
|
+
summary: List my role preferences
|
|
484
|
+
operationId: listPreferences
|
|
485
|
+
description: Every (account, role) the caller has customised — profile-name override, role label, auto-vend star.
|
|
486
|
+
responses:
|
|
487
|
+
"200":
|
|
488
|
+
description: Preference rows.
|
|
489
|
+
content:
|
|
490
|
+
application/json:
|
|
491
|
+
schema:
|
|
492
|
+
type: object
|
|
493
|
+
properties:
|
|
494
|
+
preferences:
|
|
495
|
+
type: array
|
|
496
|
+
items: { $ref: "#/components/schemas/RolePreference" }
|
|
497
|
+
required: [preferences]
|
|
498
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
499
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
500
|
+
|
|
501
|
+
/preferences/auto-vend/{accountNumber}/{role}:
|
|
502
|
+
put:
|
|
503
|
+
tags: [Preferences]
|
|
504
|
+
summary: Set the auto-vend star
|
|
505
|
+
operationId: setAutoVend
|
|
506
|
+
description: Starred roles are vended silently on app load (desktop keeps them fresh in `~/.aws/credentials`).
|
|
507
|
+
parameters:
|
|
508
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
509
|
+
- $ref: "#/components/parameters/role"
|
|
510
|
+
requestBody:
|
|
511
|
+
required: true
|
|
512
|
+
content:
|
|
513
|
+
application/json:
|
|
514
|
+
schema:
|
|
515
|
+
type: object
|
|
516
|
+
properties:
|
|
517
|
+
autoVend: { type: boolean }
|
|
518
|
+
required: [autoVend]
|
|
519
|
+
example: { autoVend: true }
|
|
520
|
+
responses:
|
|
521
|
+
"200":
|
|
522
|
+
description: The saved value.
|
|
523
|
+
content:
|
|
524
|
+
application/json:
|
|
525
|
+
schema:
|
|
526
|
+
type: object
|
|
527
|
+
properties:
|
|
528
|
+
autoVend: { type: boolean }
|
|
529
|
+
required: [autoVend]
|
|
530
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
531
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
532
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
533
|
+
|
|
534
|
+
/preferences/favorites/{accountNumber}:
|
|
535
|
+
put:
|
|
536
|
+
tags: [Preferences]
|
|
537
|
+
summary: Star or unstar an account
|
|
538
|
+
operationId: setFavorite
|
|
539
|
+
description: A starred account shows in the dashboard's Favorites section on every device. At most 50; starring a starred account changes nothing.
|
|
540
|
+
parameters:
|
|
541
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
542
|
+
requestBody:
|
|
543
|
+
required: true
|
|
544
|
+
content:
|
|
545
|
+
application/json:
|
|
546
|
+
schema:
|
|
547
|
+
type: object
|
|
548
|
+
properties:
|
|
549
|
+
favorite: { type: boolean }
|
|
550
|
+
required: [favorite]
|
|
551
|
+
responses:
|
|
552
|
+
"200":
|
|
553
|
+
description: The saved state.
|
|
554
|
+
content:
|
|
555
|
+
application/json:
|
|
556
|
+
schema:
|
|
557
|
+
type: object
|
|
558
|
+
properties:
|
|
559
|
+
favorite: { type: boolean }
|
|
560
|
+
required: [favorite]
|
|
561
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
562
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
563
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
564
|
+
|
|
565
|
+
/preferences/network:
|
|
566
|
+
get:
|
|
567
|
+
tags: [Preferences]
|
|
568
|
+
summary: Get my network preferences
|
|
569
|
+
operationId: getNetworkPrefs
|
|
570
|
+
description: Device-independent VPN preferences — the auto-reconnect toggle and the site a reconnect rejoins.
|
|
571
|
+
responses:
|
|
572
|
+
"200":
|
|
573
|
+
description: Network preferences.
|
|
574
|
+
content:
|
|
575
|
+
application/json:
|
|
576
|
+
schema: { $ref: "#/components/schemas/NetworkPrefs" }
|
|
577
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
578
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
579
|
+
put:
|
|
580
|
+
tags: [Preferences]
|
|
581
|
+
summary: Update my network preferences
|
|
582
|
+
operationId: setNetworkPrefs
|
|
583
|
+
requestBody:
|
|
584
|
+
required: true
|
|
585
|
+
content:
|
|
586
|
+
application/json:
|
|
587
|
+
schema:
|
|
588
|
+
type: object
|
|
589
|
+
description: At least one field.
|
|
590
|
+
properties:
|
|
591
|
+
autoReconnect: { type: boolean }
|
|
592
|
+
lastSiteId: { type: string, minLength: 1, maxLength: 64 }
|
|
593
|
+
example: { autoReconnect: true, lastSiteId: "dev" }
|
|
594
|
+
responses:
|
|
595
|
+
"200":
|
|
596
|
+
description: The preferences after the update.
|
|
597
|
+
content:
|
|
598
|
+
application/json:
|
|
599
|
+
schema: { $ref: "#/components/schemas/NetworkPrefs" }
|
|
600
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
601
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
602
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
603
|
+
|
|
604
|
+
/preferences/notifications:
|
|
605
|
+
get:
|
|
606
|
+
tags: [Preferences]
|
|
607
|
+
summary: Get my notification preferences
|
|
608
|
+
operationId: getNotificationPrefs
|
|
609
|
+
description: Which bell items may pop up as native notifications (desktop toasts, browser notifications). Everything is on until turned off; the row follows the user across devices.
|
|
610
|
+
responses:
|
|
611
|
+
"200":
|
|
612
|
+
description: Notification preferences.
|
|
613
|
+
content:
|
|
614
|
+
application/json:
|
|
615
|
+
schema: { $ref: "#/components/schemas/NotificationPrefs" }
|
|
616
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
617
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
618
|
+
put:
|
|
619
|
+
tags: [Preferences]
|
|
620
|
+
summary: Update my notification preferences
|
|
621
|
+
operationId: setNotificationPrefs
|
|
622
|
+
requestBody:
|
|
623
|
+
required: true
|
|
624
|
+
content:
|
|
625
|
+
application/json:
|
|
626
|
+
schema:
|
|
627
|
+
type: object
|
|
628
|
+
description: At least one field; `kinds` may be partial.
|
|
629
|
+
properties:
|
|
630
|
+
enabled: { type: boolean }
|
|
631
|
+
kinds:
|
|
632
|
+
type: object
|
|
633
|
+
additionalProperties: { type: boolean }
|
|
634
|
+
example: { enabled: true, kinds: { requests: false } }
|
|
635
|
+
responses:
|
|
636
|
+
"200":
|
|
637
|
+
description: The preferences after the update.
|
|
638
|
+
content:
|
|
639
|
+
application/json:
|
|
640
|
+
schema: { $ref: "#/components/schemas/NotificationPrefs" }
|
|
641
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
642
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
643
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
644
|
+
|
|
645
|
+
/preferences/profile-name/{accountNumber}/{role}:
|
|
646
|
+
get:
|
|
647
|
+
tags: [Preferences]
|
|
648
|
+
summary: Get my profile-name override
|
|
649
|
+
operationId: getProfileName
|
|
650
|
+
parameters:
|
|
651
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
652
|
+
- $ref: "#/components/parameters/role"
|
|
653
|
+
responses:
|
|
654
|
+
"200":
|
|
655
|
+
description: The override, or `null` when the admin default applies.
|
|
656
|
+
content:
|
|
657
|
+
application/json:
|
|
658
|
+
schema: { $ref: "#/components/schemas/ProfileNameValue" }
|
|
659
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
660
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
661
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
662
|
+
put:
|
|
663
|
+
tags: [Preferences]
|
|
664
|
+
summary: Set my profile-name override
|
|
665
|
+
operationId: setProfileName
|
|
666
|
+
description: A blank or absent `profileName` clears the override (same as DELETE).
|
|
667
|
+
parameters:
|
|
668
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
669
|
+
- $ref: "#/components/parameters/role"
|
|
670
|
+
requestBody:
|
|
671
|
+
content:
|
|
672
|
+
application/json:
|
|
673
|
+
schema:
|
|
674
|
+
type: object
|
|
675
|
+
properties:
|
|
676
|
+
profileName: { type: string, maxLength: 128 }
|
|
677
|
+
example: { profileName: "acme-prod-readonly" }
|
|
678
|
+
responses:
|
|
679
|
+
"200":
|
|
680
|
+
description: The saved value (`null` when cleared).
|
|
681
|
+
content:
|
|
682
|
+
application/json:
|
|
683
|
+
schema: { $ref: "#/components/schemas/ProfileNameValue" }
|
|
684
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
685
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
686
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
687
|
+
delete:
|
|
688
|
+
tags: [Preferences]
|
|
689
|
+
summary: Clear my profile-name override
|
|
690
|
+
operationId: clearProfileName
|
|
691
|
+
parameters:
|
|
692
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
693
|
+
- $ref: "#/components/parameters/role"
|
|
694
|
+
responses:
|
|
695
|
+
"204": { description: Cleared. }
|
|
696
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
697
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
698
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
699
|
+
|
|
700
|
+
/preferences/role-label/{accountNumber}/{role}:
|
|
701
|
+
put:
|
|
702
|
+
tags: [Preferences]
|
|
703
|
+
summary: Set my role label
|
|
704
|
+
operationId: setRoleLabel
|
|
705
|
+
description: A personal display name for the role card. Blank or absent clears it (the admin display name shows again).
|
|
706
|
+
parameters:
|
|
707
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
708
|
+
- $ref: "#/components/parameters/role"
|
|
709
|
+
requestBody:
|
|
710
|
+
content:
|
|
711
|
+
application/json:
|
|
712
|
+
schema:
|
|
713
|
+
type: object
|
|
714
|
+
properties:
|
|
715
|
+
roleLabel: { type: string, maxLength: 64 }
|
|
716
|
+
example: { roleLabel: "Prod read-only" }
|
|
717
|
+
responses:
|
|
718
|
+
"200":
|
|
719
|
+
description: The saved value (`null` when cleared).
|
|
720
|
+
content:
|
|
721
|
+
application/json:
|
|
722
|
+
schema:
|
|
723
|
+
type: object
|
|
724
|
+
properties:
|
|
725
|
+
roleLabel: { type: [string, "null"] }
|
|
726
|
+
required: [roleLabel]
|
|
727
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
728
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
729
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
730
|
+
delete:
|
|
731
|
+
tags: [Preferences]
|
|
732
|
+
summary: Clear my role label
|
|
733
|
+
operationId: clearRoleLabel
|
|
734
|
+
parameters:
|
|
735
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
736
|
+
- $ref: "#/components/parameters/role"
|
|
737
|
+
responses:
|
|
738
|
+
"204": { description: Cleared. }
|
|
739
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
740
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
741
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
742
|
+
|
|
743
|
+
/network:
|
|
744
|
+
get:
|
|
745
|
+
tags: [Network]
|
|
746
|
+
summary: Network sites
|
|
747
|
+
operationId: listNetworkSites
|
|
748
|
+
description: Whether private-network access is deployed, and the sites a device may enrol in. Split-DNS and VPC detail are admin-only (`GET /admin/network`).
|
|
749
|
+
responses:
|
|
750
|
+
"200":
|
|
751
|
+
description: Site list.
|
|
752
|
+
content:
|
|
753
|
+
application/json:
|
|
754
|
+
schema:
|
|
755
|
+
type: object
|
|
756
|
+
properties:
|
|
757
|
+
enabled: { type: boolean }
|
|
758
|
+
controlUrl:
|
|
759
|
+
type: [string, "null"]
|
|
760
|
+
description: Legacy single-site field — always the first site's control URL.
|
|
761
|
+
sites:
|
|
762
|
+
type: array
|
|
763
|
+
items: { $ref: "#/components/schemas/PublicSite" }
|
|
764
|
+
required: [enabled, controlUrl, sites]
|
|
765
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
766
|
+
|
|
767
|
+
/network/device-key:
|
|
768
|
+
post:
|
|
769
|
+
tags: [Network]
|
|
770
|
+
summary: Mint a device enrollment key
|
|
771
|
+
operationId: mintDeviceKey
|
|
772
|
+
description: |
|
|
773
|
+
A single-use, 30-minute enrollment key for ONE site, bound to the
|
|
774
|
+
caller's identity (their `sub` becomes the device's network user).
|
|
775
|
+
Reachability is enforced by the grants→ACL reconciler, not here.
|
|
776
|
+
Every mint writes an audit event (`NETWORK_KEY`).
|
|
777
|
+
requestBody:
|
|
778
|
+
content:
|
|
779
|
+
application/json:
|
|
780
|
+
schema:
|
|
781
|
+
type: object
|
|
782
|
+
properties:
|
|
783
|
+
siteId:
|
|
784
|
+
type: string
|
|
785
|
+
description: Defaults to the first site.
|
|
786
|
+
example: { siteId: "dev" }
|
|
787
|
+
responses:
|
|
788
|
+
"200":
|
|
789
|
+
description: The key and where to use it.
|
|
790
|
+
content:
|
|
791
|
+
application/json:
|
|
792
|
+
schema: { $ref: "#/components/schemas/DeviceKey" }
|
|
793
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
794
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
795
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
796
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
797
|
+
|
|
798
|
+
/network/shares:
|
|
799
|
+
get:
|
|
800
|
+
tags: [Network]
|
|
801
|
+
summary: My dev shares and what teammates share with me
|
|
802
|
+
operationId: listDevShares
|
|
803
|
+
description: |
|
|
804
|
+
Dev shares: a user exposes ONE local port on their laptop to named users/groups on the same
|
|
805
|
+
site for a bounded time. `mine` = shares the caller owns (with grantees); `sharedWithMe` = live
|
|
806
|
+
shares the caller holds directly or through a group. Expired shares are never returned.
|
|
807
|
+
Reachability is enforced by the ACL reconciler from the OWNER'S enrolled device IPs. Answers
|
|
808
|
+
while the network exists even if `devShares` was later disabled (leftover shares stay visible).
|
|
809
|
+
responses:
|
|
810
|
+
"200":
|
|
811
|
+
description: Both lists, soonest expiry first.
|
|
812
|
+
content:
|
|
813
|
+
application/json:
|
|
814
|
+
schema:
|
|
815
|
+
type: object
|
|
816
|
+
properties:
|
|
817
|
+
mine: { type: array, items: { $ref: "#/components/schemas/DevShare" } }
|
|
818
|
+
sharedWithMe: { type: array, items: { $ref: "#/components/schemas/DevShareWithMe" } }
|
|
819
|
+
required: [mine, sharedWithMe]
|
|
820
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
821
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
822
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
823
|
+
post:
|
|
824
|
+
tags: [Network]
|
|
825
|
+
summary: Start a dev share
|
|
826
|
+
operationId: createDevShare
|
|
827
|
+
description: |
|
|
828
|
+
Writes a `share#<id>` grant per grantee (users and, when `allowGroupTargets`, groups) plus the
|
|
829
|
+
share's definition, then kicks the ACL reconciler so the rule lands within seconds. `hostname`/`ip`
|
|
830
|
+
are the desktop app's own tailnet address — display-only, so grantees get a URL; the rule itself
|
|
831
|
+
targets the owner's enrolled device IPs. `hostname` must be the owner's node name on the share's
|
|
832
|
+
site (`<name>.<siteId>.tail.internal`). Duration is capped by `network.devShares.maxDurationHours`.
|
|
833
|
+
At most 10 live shares per owner, one per port. 501 while `devShares` is disabled.
|
|
834
|
+
requestBody:
|
|
835
|
+
required: true
|
|
836
|
+
content:
|
|
837
|
+
application/json:
|
|
838
|
+
schema:
|
|
839
|
+
type: object
|
|
840
|
+
properties:
|
|
841
|
+
port: { type: integer, minimum: 1, maximum: 65535 }
|
|
842
|
+
label: { type: string, maxLength: 60, description: "Defaults to \"Port <port>\"." }
|
|
843
|
+
siteId: { type: string, description: Defaults to the first site. }
|
|
844
|
+
durationHours: { type: integer, minimum: 1 }
|
|
845
|
+
hostname: { type: string, description: The owner's MagicDNS name. }
|
|
846
|
+
ip: { type: string, description: The owner's tailnet IPv4 (100.64.0.0/10). }
|
|
847
|
+
grantees:
|
|
848
|
+
type: array
|
|
849
|
+
minItems: 1
|
|
850
|
+
maxItems: 50
|
|
851
|
+
items:
|
|
852
|
+
type: object
|
|
853
|
+
properties:
|
|
854
|
+
kind: { type: string, enum: [user, group] }
|
|
855
|
+
id: { type: string }
|
|
856
|
+
required: [kind, id]
|
|
857
|
+
required: [port, durationHours, grantees]
|
|
858
|
+
example:
|
|
859
|
+
port: 4200
|
|
860
|
+
label: Checkout redesign
|
|
861
|
+
siteId: dev
|
|
862
|
+
durationHours: 8
|
|
863
|
+
hostname: devs-macbook.dev.tail.internal
|
|
864
|
+
grantees: [{ kind: user, id: 8d2c…-sub }, { kind: group, id: 1f4a…-group }]
|
|
865
|
+
responses:
|
|
866
|
+
"201":
|
|
867
|
+
description: The new share as its owner sees it.
|
|
868
|
+
content:
|
|
869
|
+
application/json:
|
|
870
|
+
schema:
|
|
871
|
+
type: object
|
|
872
|
+
properties:
|
|
873
|
+
share: { $ref: "#/components/schemas/DevShare" }
|
|
874
|
+
required: [share]
|
|
875
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
876
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
877
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
878
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
879
|
+
|
|
880
|
+
/network/shares/directory:
|
|
881
|
+
get:
|
|
882
|
+
tags: [Network]
|
|
883
|
+
summary: Who a dev share can target
|
|
884
|
+
operationId: listDevShareDirectory
|
|
885
|
+
description: |
|
|
886
|
+
The one directory read open to non-admins, and deliberately thin: every user's sub + email
|
|
887
|
+
(invited-but-unconfirmed users omitted) and every group's id, name and member count. 501 while
|
|
888
|
+
`devShares` is disabled.
|
|
889
|
+
responses:
|
|
890
|
+
"200":
|
|
891
|
+
description: Users and groups, sorted by email / name.
|
|
892
|
+
content:
|
|
893
|
+
application/json:
|
|
894
|
+
schema: { $ref: "#/components/schemas/DevShareDirectory" }
|
|
895
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
896
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
897
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
898
|
+
|
|
899
|
+
/network/shares/{shareId}:
|
|
900
|
+
delete:
|
|
901
|
+
tags: [Network]
|
|
902
|
+
summary: Stop a dev share
|
|
903
|
+
operationId: deleteDevShare
|
|
904
|
+
description: |
|
|
905
|
+
Owner or admin. Every grant row and the definition go; grantees who lose access get a revocation
|
|
906
|
+
notice of kind `SHARE` (via `OWNER`, or `ADMIN` when an admin stopped it). Kicks the reconciler.
|
|
907
|
+
Works while the network exists even if `devShares` was later disabled.
|
|
908
|
+
parameters:
|
|
909
|
+
- name: shareId
|
|
910
|
+
in: path
|
|
911
|
+
required: true
|
|
912
|
+
schema: { type: string, pattern: "^[a-f0-9]{12}$" }
|
|
913
|
+
responses:
|
|
914
|
+
"204": { description: Stopped. }
|
|
915
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
916
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
917
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
918
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
919
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
920
|
+
|
|
921
|
+
/resources:
|
|
922
|
+
get:
|
|
923
|
+
tags: [Resources]
|
|
924
|
+
summary: My reachable resources
|
|
925
|
+
operationId: listReachableResources
|
|
926
|
+
description: Private-network resources the caller holds an active grant on — the only place connection details (`cidr`, `ports`, `dnsName`) are exposed to non-admins.
|
|
927
|
+
responses:
|
|
928
|
+
"200":
|
|
929
|
+
description: Reachable resources, sorted by name.
|
|
930
|
+
content:
|
|
931
|
+
application/json:
|
|
932
|
+
schema:
|
|
933
|
+
type: object
|
|
934
|
+
properties:
|
|
935
|
+
resources:
|
|
936
|
+
type: array
|
|
937
|
+
items: { $ref: "#/components/schemas/ReachableResource" }
|
|
938
|
+
required: [resources]
|
|
939
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
940
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
941
|
+
|
|
942
|
+
/resources/expiry:
|
|
943
|
+
get:
|
|
944
|
+
tags: [Resources]
|
|
945
|
+
summary: My resource expiry notices
|
|
946
|
+
operationId: listResourceExpiryNotices
|
|
947
|
+
responses:
|
|
948
|
+
"200":
|
|
949
|
+
description: Temporary resource grants nearing / past their end.
|
|
950
|
+
content:
|
|
951
|
+
application/json:
|
|
952
|
+
schema:
|
|
953
|
+
type: object
|
|
954
|
+
properties:
|
|
955
|
+
expiring:
|
|
956
|
+
type: array
|
|
957
|
+
items: { $ref: "#/components/schemas/ResourceExpiryNotice" }
|
|
958
|
+
expired:
|
|
959
|
+
type: array
|
|
960
|
+
items: { $ref: "#/components/schemas/ResourceExpiryNotice" }
|
|
961
|
+
required: [expiring, expired]
|
|
962
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
963
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
964
|
+
|
|
965
|
+
/resources/expiry/seen:
|
|
966
|
+
post:
|
|
967
|
+
tags: [Resources]
|
|
968
|
+
summary: Acknowledge resource expiry notices
|
|
969
|
+
operationId: markResourceExpiryNoticesSeen
|
|
970
|
+
responses:
|
|
971
|
+
"200":
|
|
972
|
+
description: How many notices were newly marked seen.
|
|
973
|
+
content:
|
|
974
|
+
application/json:
|
|
975
|
+
schema: { $ref: "#/components/schemas/Cleared" }
|
|
976
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
977
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
978
|
+
|
|
979
|
+
/notifications/revocations:
|
|
980
|
+
get:
|
|
981
|
+
tags: [Notifications]
|
|
982
|
+
summary: My revocation notices
|
|
983
|
+
operationId: listRevocationNotices
|
|
984
|
+
description: Access the caller lost (admin revoke, group change, reapproval, cascade), newest first. Kept 30 days.
|
|
985
|
+
responses:
|
|
986
|
+
"200":
|
|
987
|
+
description: Revocation notices.
|
|
988
|
+
content:
|
|
989
|
+
application/json:
|
|
990
|
+
schema:
|
|
991
|
+
type: object
|
|
992
|
+
properties:
|
|
993
|
+
notices:
|
|
994
|
+
type: array
|
|
995
|
+
items: { $ref: "#/components/schemas/RevocationNotice" }
|
|
996
|
+
required: [notices]
|
|
997
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
998
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
999
|
+
|
|
1000
|
+
/notifications/revocations/seen:
|
|
1001
|
+
post:
|
|
1002
|
+
tags: [Notifications]
|
|
1003
|
+
summary: Acknowledge revocation notices
|
|
1004
|
+
operationId: markRevocationNoticesSeen
|
|
1005
|
+
responses:
|
|
1006
|
+
"200":
|
|
1007
|
+
description: How many notices were newly marked seen.
|
|
1008
|
+
content:
|
|
1009
|
+
application/json:
|
|
1010
|
+
schema: { $ref: "#/components/schemas/Cleared" }
|
|
1011
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1012
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1013
|
+
|
|
1014
|
+
# ---------------------------------------------------------------- admin ---
|
|
1015
|
+
|
|
1016
|
+
/admin/setup:
|
|
1017
|
+
get:
|
|
1018
|
+
tags: ["Admin: setup"]
|
|
1019
|
+
summary: Setup checklist state
|
|
1020
|
+
operationId: getSetupStatus
|
|
1021
|
+
description: First-run checklist inputs, aggregated live — items check themselves off as the deployment fills in.
|
|
1022
|
+
responses:
|
|
1023
|
+
"200":
|
|
1024
|
+
description: Setup status.
|
|
1025
|
+
content:
|
|
1026
|
+
application/json:
|
|
1027
|
+
schema: { $ref: "#/components/schemas/SetupStatus" }
|
|
1028
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1029
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1030
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1031
|
+
|
|
1032
|
+
/admin/branding:
|
|
1033
|
+
put:
|
|
1034
|
+
tags: ["Admin: setup"]
|
|
1035
|
+
summary: Save the branding overlay
|
|
1036
|
+
operationId: saveBranding
|
|
1037
|
+
description: Writes `/branding.json` in the web bucket (the SPA fetches it from the web origin at boot — there is no GET here). `dismissed` hides the first-admin theme wizard.
|
|
1038
|
+
requestBody:
|
|
1039
|
+
required: true
|
|
1040
|
+
content:
|
|
1041
|
+
application/json:
|
|
1042
|
+
schema:
|
|
1043
|
+
type: object
|
|
1044
|
+
description: At least one of `branding`, `dismissed`.
|
|
1045
|
+
properties:
|
|
1046
|
+
branding: { $ref: "#/components/schemas/BrandingOverlay" }
|
|
1047
|
+
dismissed: { type: boolean }
|
|
1048
|
+
example: { branding: { projectName: "Acme Access", primaryColor: "#3e63dd" }, dismissed: true }
|
|
1049
|
+
responses:
|
|
1050
|
+
"204": { description: Saved. }
|
|
1051
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1052
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1053
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1054
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
1055
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1056
|
+
|
|
1057
|
+
/admin/accounts:
|
|
1058
|
+
get:
|
|
1059
|
+
tags: ["Admin: accounts & roles"]
|
|
1060
|
+
summary: List the catalog
|
|
1061
|
+
operationId: adminListAccounts
|
|
1062
|
+
description: |
|
|
1063
|
+
Every registered account with its roles; each role carries its unexpired-grantee count.
|
|
1064
|
+
With `limit`, one page of the list contract: sorts `position` (the admin order, default), `name`, `number`; facets `environment`, `status`, `main` (`true`/`false`), plus `tenant`, `project`, `stage` on a deployment with account dimensions (`unclassified` for an account without one).
|
|
1065
|
+
parameters:
|
|
1066
|
+
- $ref: "#/components/parameters/listQ"
|
|
1067
|
+
- $ref: "#/components/parameters/listFilter"
|
|
1068
|
+
- $ref: "#/components/parameters/listSort"
|
|
1069
|
+
- $ref: "#/components/parameters/listLimit"
|
|
1070
|
+
- $ref: "#/components/parameters/listCursor"
|
|
1071
|
+
responses:
|
|
1072
|
+
"200":
|
|
1073
|
+
description: The catalog — the whole list, or one page when `limit` was passed.
|
|
1074
|
+
content:
|
|
1075
|
+
application/json:
|
|
1076
|
+
schema:
|
|
1077
|
+
oneOf:
|
|
1078
|
+
- type: object
|
|
1079
|
+
properties:
|
|
1080
|
+
accounts:
|
|
1081
|
+
type: array
|
|
1082
|
+
items: { $ref: "#/components/schemas/AdminAccount" }
|
|
1083
|
+
required: [accounts]
|
|
1084
|
+
- $ref: "#/components/schemas/AdminAccountPage"
|
|
1085
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1086
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1087
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1088
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1089
|
+
post:
|
|
1090
|
+
tags: ["Admin: accounts & roles"]
|
|
1091
|
+
summary: Register an account
|
|
1092
|
+
operationId: adminCreateAccount
|
|
1093
|
+
requestBody:
|
|
1094
|
+
required: true
|
|
1095
|
+
content:
|
|
1096
|
+
application/json:
|
|
1097
|
+
schema: { $ref: "#/components/schemas/AccountCreate" }
|
|
1098
|
+
example: { accountNumber: "123456789012", name: "Production", environment: "prod", profileName: "acme-prod" }
|
|
1099
|
+
responses:
|
|
1100
|
+
"201":
|
|
1101
|
+
description: The account.
|
|
1102
|
+
content:
|
|
1103
|
+
application/json:
|
|
1104
|
+
schema: { $ref: "#/components/schemas/AccountEnvelope" }
|
|
1105
|
+
"200":
|
|
1106
|
+
description: Already registered with the same values (a retry); the stored account, nothing changed. Different values are a `409`.
|
|
1107
|
+
content:
|
|
1108
|
+
application/json:
|
|
1109
|
+
schema: { $ref: "#/components/schemas/AccountEnvelope" }
|
|
1110
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1111
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1112
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1113
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1114
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1115
|
+
|
|
1116
|
+
/admin/dashboard-layout:
|
|
1117
|
+
get:
|
|
1118
|
+
tags: ["Admin: accounts & roles"]
|
|
1119
|
+
summary: The deployment-wide dashboard layout
|
|
1120
|
+
operationId: adminGetDashboardLayout
|
|
1121
|
+
description: |
|
|
1122
|
+
How every user's dashboard is laid out. `auto` (the default): a user gets Main / Favorites / Recent and the
|
|
1123
|
+
search once they hold an account an admin took off the Main section, and the plain list until then — so a
|
|
1124
|
+
deployment that never touches the Main flag looks as it always did. `sections`: everyone gets the sections.
|
|
1125
|
+
`plain`: nobody does. The per-account "Show in the Main section" flag still decides what sits in Main.
|
|
1126
|
+
responses:
|
|
1127
|
+
"200":
|
|
1128
|
+
description: The current mode.
|
|
1129
|
+
content:
|
|
1130
|
+
application/json:
|
|
1131
|
+
schema: { $ref: "#/components/schemas/DashboardLayout" }
|
|
1132
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1133
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1134
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1135
|
+
put:
|
|
1136
|
+
tags: ["Admin: accounts & roles"]
|
|
1137
|
+
summary: Set the deployment-wide dashboard layout
|
|
1138
|
+
operationId: adminSetDashboardLayout
|
|
1139
|
+
description: Takes effect on each user's next dashboard load; a change is recorded in the activity log.
|
|
1140
|
+
requestBody:
|
|
1141
|
+
required: true
|
|
1142
|
+
content:
|
|
1143
|
+
application/json:
|
|
1144
|
+
schema: { $ref: "#/components/schemas/DashboardLayout" }
|
|
1145
|
+
responses:
|
|
1146
|
+
"200":
|
|
1147
|
+
description: The stored mode.
|
|
1148
|
+
content:
|
|
1149
|
+
application/json:
|
|
1150
|
+
schema: { $ref: "#/components/schemas/DashboardLayout" }
|
|
1151
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1152
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1153
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1154
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1155
|
+
/admin/accounts/order:
|
|
1156
|
+
put:
|
|
1157
|
+
tags: ["Admin: accounts & roles"]
|
|
1158
|
+
summary: Set the display order of the accounts
|
|
1159
|
+
operationId: adminReorderAccounts
|
|
1160
|
+
description: The whole list, first to last; each account's position becomes its index, and each listed role's its position inside its account. This is the order every page shows to every user (Your access and the admin tabs). Accounts left out, and roles left out of an account's list, lose any position they had and list after the ordered ones, by name.
|
|
1161
|
+
requestBody:
|
|
1162
|
+
required: true
|
|
1163
|
+
content:
|
|
1164
|
+
application/json:
|
|
1165
|
+
schema: { $ref: "#/components/schemas/AccountOrder" }
|
|
1166
|
+
example: { accounts: [{ accountNumber: "111111111111", roles: ["DevRole", "AdminRole"] }, { accountNumber: "222222222222" }] }
|
|
1167
|
+
responses:
|
|
1168
|
+
"200":
|
|
1169
|
+
description: The ordered accounts as stored, in the new order — only the ones the request listed, never the whole catalog.
|
|
1170
|
+
content:
|
|
1171
|
+
application/json:
|
|
1172
|
+
schema:
|
|
1173
|
+
type: object
|
|
1174
|
+
properties:
|
|
1175
|
+
accounts:
|
|
1176
|
+
type: array
|
|
1177
|
+
items: { $ref: "#/components/schemas/AdminAccount" }
|
|
1178
|
+
required: [accounts]
|
|
1179
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1180
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1181
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1182
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1183
|
+
/admin/accounts/{accountNumber}:
|
|
1184
|
+
get:
|
|
1185
|
+
tags: ["Admin: accounts & roles"]
|
|
1186
|
+
summary: Get one account
|
|
1187
|
+
operationId: adminGetAccount
|
|
1188
|
+
parameters:
|
|
1189
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1190
|
+
responses:
|
|
1191
|
+
"200":
|
|
1192
|
+
description: The account with its roles.
|
|
1193
|
+
content:
|
|
1194
|
+
application/json:
|
|
1195
|
+
schema: { $ref: "#/components/schemas/AccountEnvelope" }
|
|
1196
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1197
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1198
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1199
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1200
|
+
patch:
|
|
1201
|
+
tags: ["Admin: accounts & roles"]
|
|
1202
|
+
summary: Update an account
|
|
1203
|
+
operationId: adminUpdateAccount
|
|
1204
|
+
description: At least one field. `profileName` is the `~/.aws` profile users get when they hold exactly one role here; `""` clears it; it must be unique across accounts and roles (`409`).
|
|
1205
|
+
parameters:
|
|
1206
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1207
|
+
requestBody:
|
|
1208
|
+
required: true
|
|
1209
|
+
content:
|
|
1210
|
+
application/json:
|
|
1211
|
+
schema: { $ref: "#/components/schemas/AccountPatch" }
|
|
1212
|
+
example: { name: "Production (EU)", status: "active" }
|
|
1213
|
+
responses:
|
|
1214
|
+
"200":
|
|
1215
|
+
description: The updated account.
|
|
1216
|
+
content:
|
|
1217
|
+
application/json:
|
|
1218
|
+
schema: { $ref: "#/components/schemas/AccountEnvelope" }
|
|
1219
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1220
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1221
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1222
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1223
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1224
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1225
|
+
delete:
|
|
1226
|
+
tags: ["Admin: accounts & roles"]
|
|
1227
|
+
summary: Remove an account
|
|
1228
|
+
operationId: adminDeleteAccount
|
|
1229
|
+
description: "**Cascades**: for each of the account's roles, every grant is revoked (losses are noticed), group bundles drop it and its open requests are denied with the reason; then the roles and the account go. Refused with 409 while the account still has network resources — remove those first. Grants go before the catalog rows, so a call that failed halfway can be repeated."
|
|
1230
|
+
parameters:
|
|
1231
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1232
|
+
responses:
|
|
1233
|
+
"204": { description: Removed. }
|
|
1234
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1235
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1236
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1237
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1238
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1239
|
+
|
|
1240
|
+
/admin/accounts/{accountNumber}/roles:
|
|
1241
|
+
post:
|
|
1242
|
+
tags: ["Admin: accounts & roles"]
|
|
1243
|
+
summary: Add a role
|
|
1244
|
+
operationId: adminCreateRole
|
|
1245
|
+
description: Registers a role users can be granted. Auto-registers the account if it is not catalogued yet. The ARN's account must equal the path's `accountNumber`.
|
|
1246
|
+
parameters:
|
|
1247
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1248
|
+
requestBody:
|
|
1249
|
+
required: true
|
|
1250
|
+
content:
|
|
1251
|
+
application/json:
|
|
1252
|
+
schema: { $ref: "#/components/schemas/RoleCreate" }
|
|
1253
|
+
example: { roleName: "ReadOnly", displayName: "Read only", roleArn: "arn:aws:iam::123456789012:role/ReadOnly", policyTier: "READ_ONLY", sessionDurationSeconds: 3600, icon: "view" }
|
|
1254
|
+
responses:
|
|
1255
|
+
"201":
|
|
1256
|
+
description: The role.
|
|
1257
|
+
content:
|
|
1258
|
+
application/json:
|
|
1259
|
+
schema: { $ref: "#/components/schemas/RoleEnvelope" }
|
|
1260
|
+
"200":
|
|
1261
|
+
description: Already registered with the same values (a retry); the stored role, nothing changed. Different values, or a name that differs only in case, are a `409`.
|
|
1262
|
+
content:
|
|
1263
|
+
application/json:
|
|
1264
|
+
schema: { $ref: "#/components/schemas/RoleEnvelope" }
|
|
1265
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1266
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1267
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1268
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1269
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1270
|
+
|
|
1271
|
+
/admin/accounts/{accountNumber}/roles/{roleName}:
|
|
1272
|
+
patch:
|
|
1273
|
+
tags: ["Admin: accounts & roles"]
|
|
1274
|
+
summary: Update a role
|
|
1275
|
+
operationId: adminUpdateRole
|
|
1276
|
+
description: At least one field. `sessionDurationSeconds` (900–43200) is what vends ask STS for; `profileName` must be unique across accounts and roles (`409`).
|
|
1277
|
+
parameters:
|
|
1278
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1279
|
+
- $ref: "#/components/parameters/roleName"
|
|
1280
|
+
requestBody:
|
|
1281
|
+
required: true
|
|
1282
|
+
content:
|
|
1283
|
+
application/json:
|
|
1284
|
+
schema: { $ref: "#/components/schemas/RolePatch" }
|
|
1285
|
+
example: { displayName: "Read only (EU)", sessionDurationSeconds: 7200, color: "#3e63dd" }
|
|
1286
|
+
responses:
|
|
1287
|
+
"200":
|
|
1288
|
+
description: The updated role.
|
|
1289
|
+
content:
|
|
1290
|
+
application/json:
|
|
1291
|
+
schema: { $ref: "#/components/schemas/RoleEnvelope" }
|
|
1292
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1293
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1294
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1295
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1296
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1297
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1298
|
+
delete:
|
|
1299
|
+
tags: ["Admin: accounts & roles"]
|
|
1300
|
+
summary: Remove a role
|
|
1301
|
+
operationId: adminDeleteRole
|
|
1302
|
+
description: "**Cascades**: every grant on the role is revoked (losses are noticed), groups bundling it drop it (a group left empty is removed), and its open requests and reviews are denied with the reason. Grants go before the catalog row, so a call that failed halfway can be repeated: an already-removed role still sweeps its leftovers before the 404."
|
|
1303
|
+
parameters:
|
|
1304
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1305
|
+
- $ref: "#/components/parameters/roleName"
|
|
1306
|
+
responses:
|
|
1307
|
+
"204": { description: Removed. }
|
|
1308
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1309
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1310
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1311
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1312
|
+
|
|
1313
|
+
/admin/accounts/{accountNumber}/roles/{roleName}/test-session:
|
|
1314
|
+
post:
|
|
1315
|
+
tags: ["Admin: accounts & roles"]
|
|
1316
|
+
summary: Test a session length
|
|
1317
|
+
operationId: adminTestSession
|
|
1318
|
+
description: "Tries `AssumeRoleWithWebIdentity` as the calling admin for `durationSeconds`, discarding the credentials. `ok: false` carries STS's message (usually the IAM role's MaxSessionDuration is lower)."
|
|
1319
|
+
parameters:
|
|
1320
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1321
|
+
- $ref: "#/components/parameters/roleName"
|
|
1322
|
+
requestBody:
|
|
1323
|
+
required: true
|
|
1324
|
+
content:
|
|
1325
|
+
application/json:
|
|
1326
|
+
schema:
|
|
1327
|
+
type: object
|
|
1328
|
+
properties:
|
|
1329
|
+
durationSeconds: { type: integer, minimum: 900, maximum: 43200 }
|
|
1330
|
+
required: [durationSeconds]
|
|
1331
|
+
example: { durationSeconds: 14400 }
|
|
1332
|
+
responses:
|
|
1333
|
+
"200":
|
|
1334
|
+
description: The outcome.
|
|
1335
|
+
content:
|
|
1336
|
+
application/json:
|
|
1337
|
+
schema: { $ref: "#/components/schemas/TestSessionResult" }
|
|
1338
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1339
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1340
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1341
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1342
|
+
|
|
1343
|
+
/admin/accounts/{accountNumber}/roles/{roleName}/grants:
|
|
1344
|
+
get:
|
|
1345
|
+
tags: ["Admin: grants"]
|
|
1346
|
+
summary: Who holds this role
|
|
1347
|
+
operationId: adminListGrantees
|
|
1348
|
+
parameters:
|
|
1349
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1350
|
+
- $ref: "#/components/parameters/roleName"
|
|
1351
|
+
responses:
|
|
1352
|
+
"200":
|
|
1353
|
+
description: Holders, direct and via groups.
|
|
1354
|
+
content:
|
|
1355
|
+
application/json:
|
|
1356
|
+
schema:
|
|
1357
|
+
type: object
|
|
1358
|
+
properties:
|
|
1359
|
+
grantees:
|
|
1360
|
+
type: array
|
|
1361
|
+
items: { $ref: "#/components/schemas/Grantee" }
|
|
1362
|
+
required: [grantees]
|
|
1363
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1364
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1365
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1366
|
+
|
|
1367
|
+
/admin/accounts/{accountNumber}/roles/{roleName}/grants/{userId}:
|
|
1368
|
+
put:
|
|
1369
|
+
tags: ["Admin: grants"]
|
|
1370
|
+
summary: Grant a role
|
|
1371
|
+
operationId: adminAssignRole
|
|
1372
|
+
description: Idempotent. `durationHours` makes the grant temporary; re-granting overwrites the expiry (the "extend" path). A long-term grant is never downgraded to temporary. `userId` may be a service user's client id.
|
|
1373
|
+
parameters:
|
|
1374
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1375
|
+
- $ref: "#/components/parameters/roleName"
|
|
1376
|
+
- $ref: "#/components/parameters/userId"
|
|
1377
|
+
requestBody:
|
|
1378
|
+
content:
|
|
1379
|
+
application/json:
|
|
1380
|
+
schema:
|
|
1381
|
+
type: object
|
|
1382
|
+
properties:
|
|
1383
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
1384
|
+
example: { durationHours: 24 }
|
|
1385
|
+
responses:
|
|
1386
|
+
"200":
|
|
1387
|
+
description: The grant as stored.
|
|
1388
|
+
content:
|
|
1389
|
+
application/json:
|
|
1390
|
+
schema:
|
|
1391
|
+
type: object
|
|
1392
|
+
properties:
|
|
1393
|
+
grant: { $ref: "#/components/schemas/Grant" }
|
|
1394
|
+
required: [grant]
|
|
1395
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1396
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1397
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1398
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1399
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1400
|
+
delete:
|
|
1401
|
+
tags: ["Admin: grants"]
|
|
1402
|
+
summary: Revoke a role
|
|
1403
|
+
operationId: adminRevokeRole
|
|
1404
|
+
description: Removes the direct grant only — group-provided access stays (change the group instead). The loss is noticed if it ends the user's access.
|
|
1405
|
+
parameters:
|
|
1406
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
1407
|
+
- $ref: "#/components/parameters/roleName"
|
|
1408
|
+
- $ref: "#/components/parameters/userId"
|
|
1409
|
+
responses:
|
|
1410
|
+
"204": { description: Revoked. }
|
|
1411
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1412
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1413
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1414
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1415
|
+
|
|
1416
|
+
/admin/grants/bulk:
|
|
1417
|
+
post:
|
|
1418
|
+
tags: ["Admin: grants"]
|
|
1419
|
+
summary: Grant roles in bulk
|
|
1420
|
+
operationId: adminBulkAssign
|
|
1421
|
+
description: Up to 20 roles × 50 users in one call. Always `200` with a per-pair result — one bad pair never fails the rest.
|
|
1422
|
+
requestBody:
|
|
1423
|
+
required: true
|
|
1424
|
+
content:
|
|
1425
|
+
application/json:
|
|
1426
|
+
schema:
|
|
1427
|
+
type: object
|
|
1428
|
+
properties:
|
|
1429
|
+
userIds: { type: array, items: { type: string }, minItems: 1, maxItems: 50 }
|
|
1430
|
+
roles: { type: array, items: { $ref: "#/components/schemas/RoleRef" }, minItems: 1, maxItems: 20 }
|
|
1431
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
1432
|
+
required: [userIds, roles]
|
|
1433
|
+
example: { userIds: ["1a2b3c4d-0000-4000-8000-000000000000"], roles: [{ accountNumber: "123456789012", roleName: "ReadOnly" }], durationHours: 168 }
|
|
1434
|
+
responses:
|
|
1435
|
+
"200":
|
|
1436
|
+
description: Per-pair results.
|
|
1437
|
+
content:
|
|
1438
|
+
application/json:
|
|
1439
|
+
schema:
|
|
1440
|
+
type: object
|
|
1441
|
+
properties:
|
|
1442
|
+
results:
|
|
1443
|
+
type: array
|
|
1444
|
+
items: { $ref: "#/components/schemas/BulkAssignResult" }
|
|
1445
|
+
required: [results]
|
|
1446
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1447
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1448
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1449
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1450
|
+
|
|
1451
|
+
/admin/grants/bulk-revoke:
|
|
1452
|
+
post:
|
|
1453
|
+
tags: ["Admin: grants"]
|
|
1454
|
+
summary: Revoke roles in bulk
|
|
1455
|
+
operationId: adminBulkRevoke
|
|
1456
|
+
description: Always `200` with per-pair results — pairs with no direct grant are `SKIPPED`; group-provided pairs `FAILED` (membership, not a direct revoke, removes those).
|
|
1457
|
+
requestBody:
|
|
1458
|
+
required: true
|
|
1459
|
+
content:
|
|
1460
|
+
application/json:
|
|
1461
|
+
schema:
|
|
1462
|
+
type: object
|
|
1463
|
+
properties:
|
|
1464
|
+
userIds: { type: array, items: { type: string }, minItems: 1, maxItems: 50 }
|
|
1465
|
+
roles: { type: array, items: { $ref: "#/components/schemas/RoleRef" }, minItems: 1, maxItems: 20 }
|
|
1466
|
+
required: [userIds, roles]
|
|
1467
|
+
example: { userIds: ["1a2b3c4d-0000-4000-8000-000000000000"], roles: [{ accountNumber: "123456789012", roleName: "ReadOnly" }] }
|
|
1468
|
+
responses:
|
|
1469
|
+
"200":
|
|
1470
|
+
description: Per-pair results.
|
|
1471
|
+
content:
|
|
1472
|
+
application/json:
|
|
1473
|
+
schema:
|
|
1474
|
+
type: object
|
|
1475
|
+
properties:
|
|
1476
|
+
results:
|
|
1477
|
+
type: array
|
|
1478
|
+
items: { $ref: "#/components/schemas/BulkRevokeResult" }
|
|
1479
|
+
required: [results]
|
|
1480
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1481
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1482
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1483
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1484
|
+
|
|
1485
|
+
/admin/users:
|
|
1486
|
+
get:
|
|
1487
|
+
tags: ["Admin: users"]
|
|
1488
|
+
summary: List users
|
|
1489
|
+
operationId: adminListUsers
|
|
1490
|
+
description: |
|
|
1491
|
+
The Cognito directory (source of truth — a user with no grants still appears) with each user's effective roles and resources.
|
|
1492
|
+
With `limit`, one page of the list contract: sorts `email` (default), `lastSeen`; facets `admin` (`admin`/`member`), `status` (`invited`/`active`).
|
|
1493
|
+
parameters:
|
|
1494
|
+
- $ref: "#/components/parameters/listQ"
|
|
1495
|
+
- $ref: "#/components/parameters/listFilter"
|
|
1496
|
+
- $ref: "#/components/parameters/listSort"
|
|
1497
|
+
- $ref: "#/components/parameters/listLimit"
|
|
1498
|
+
- $ref: "#/components/parameters/listCursor"
|
|
1499
|
+
responses:
|
|
1500
|
+
"200":
|
|
1501
|
+
description: Users — the whole list, or one page when `limit` was passed.
|
|
1502
|
+
content:
|
|
1503
|
+
application/json:
|
|
1504
|
+
schema:
|
|
1505
|
+
oneOf:
|
|
1506
|
+
- type: object
|
|
1507
|
+
properties:
|
|
1508
|
+
users:
|
|
1509
|
+
type: array
|
|
1510
|
+
items: { $ref: "#/components/schemas/User" }
|
|
1511
|
+
required: [users]
|
|
1512
|
+
- $ref: "#/components/schemas/UserPage"
|
|
1513
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1514
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1515
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1516
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1517
|
+
post:
|
|
1518
|
+
tags: ["Admin: users"]
|
|
1519
|
+
summary: Invite a user
|
|
1520
|
+
operationId: adminCreateUser
|
|
1521
|
+
description: Creates the Cognito user and, unless `sendEmail` is `false`, **sends the invitation email**. The response carries the sign-up link either way — the same `/login#inv=…` link the email holds, valid 7 days; anyone holding it can set the password. `409` if the email is taken.
|
|
1522
|
+
requestBody:
|
|
1523
|
+
required: true
|
|
1524
|
+
content:
|
|
1525
|
+
application/json:
|
|
1526
|
+
schema:
|
|
1527
|
+
type: object
|
|
1528
|
+
properties:
|
|
1529
|
+
email: { type: string, format: email }
|
|
1530
|
+
admin: { type: boolean, default: false, description: Also add to the `admins` group. }
|
|
1531
|
+
sendEmail: { type: boolean, default: true, description: "`false`: Cognito emails nothing and the response carries `signupLink` for you to pass on." }
|
|
1532
|
+
required: [email]
|
|
1533
|
+
example: { email: "new.user@example.com", admin: false, sendEmail: true }
|
|
1534
|
+
responses:
|
|
1535
|
+
"201":
|
|
1536
|
+
description: "The new user (`pendingInvite: true`), plus `signupLink` only when `sendEmail` was `false`."
|
|
1537
|
+
content:
|
|
1538
|
+
application/json:
|
|
1539
|
+
schema:
|
|
1540
|
+
type: object
|
|
1541
|
+
properties:
|
|
1542
|
+
user: { $ref: "#/components/schemas/User" }
|
|
1543
|
+
signupLink: { type: string, description: "Only when `sendEmail` was `false` — it carries the temporary password. Absolute when the deploy has a web domain, else path-only (`/login#inv=…`)." }
|
|
1544
|
+
required: [user]
|
|
1545
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1546
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1547
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1548
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1549
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1550
|
+
|
|
1551
|
+
/admin/users/bulk:
|
|
1552
|
+
post:
|
|
1553
|
+
tags: ["Admin: users"]
|
|
1554
|
+
summary: Invite users in bulk
|
|
1555
|
+
operationId: adminBulkCreateUsers
|
|
1556
|
+
description: Up to 50 emails. Always `200` with a per-row `CREATED`/`FAILED` result — one taken email never fails the rest. Each `CREATED` row sent a real invitation email, or — with `sendEmail` `false` — carries its `signupLink` instead.
|
|
1557
|
+
requestBody:
|
|
1558
|
+
required: true
|
|
1559
|
+
content:
|
|
1560
|
+
application/json:
|
|
1561
|
+
schema:
|
|
1562
|
+
type: object
|
|
1563
|
+
properties:
|
|
1564
|
+
emails: { type: array, items: { type: string, format: email }, minItems: 1, maxItems: 50 }
|
|
1565
|
+
admin: { type: boolean, default: false }
|
|
1566
|
+
sendEmail: { type: boolean, default: true }
|
|
1567
|
+
required: [emails]
|
|
1568
|
+
example: { emails: ["a@example.com", "b@example.com"], admin: false }
|
|
1569
|
+
responses:
|
|
1570
|
+
"200":
|
|
1571
|
+
description: Per-row results.
|
|
1572
|
+
content:
|
|
1573
|
+
application/json:
|
|
1574
|
+
schema:
|
|
1575
|
+
type: object
|
|
1576
|
+
properties:
|
|
1577
|
+
results:
|
|
1578
|
+
type: array
|
|
1579
|
+
items: { $ref: "#/components/schemas/BulkCreateResult" }
|
|
1580
|
+
required: [results]
|
|
1581
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1582
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1583
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1584
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1585
|
+
|
|
1586
|
+
/admin/users/bulk-delete:
|
|
1587
|
+
post:
|
|
1588
|
+
tags: ["Admin: users"]
|
|
1589
|
+
summary: Delete users in bulk
|
|
1590
|
+
operationId: adminBulkDeleteUsers
|
|
1591
|
+
description: Up to 50 users, each with the full delete cascade. Always `200` with per-row results; the caller's own account is refused so a sweep can never lock everyone out.
|
|
1592
|
+
requestBody:
|
|
1593
|
+
required: true
|
|
1594
|
+
content:
|
|
1595
|
+
application/json:
|
|
1596
|
+
schema:
|
|
1597
|
+
type: object
|
|
1598
|
+
properties:
|
|
1599
|
+
userIds: { type: array, items: { type: string }, minItems: 1, maxItems: 50 }
|
|
1600
|
+
required: [userIds]
|
|
1601
|
+
example: { userIds: ["1a2b3c4d-0000-4000-8000-000000000000"] }
|
|
1602
|
+
responses:
|
|
1603
|
+
"200":
|
|
1604
|
+
description: Per-row results.
|
|
1605
|
+
content:
|
|
1606
|
+
application/json:
|
|
1607
|
+
schema:
|
|
1608
|
+
type: object
|
|
1609
|
+
properties:
|
|
1610
|
+
results:
|
|
1611
|
+
type: array
|
|
1612
|
+
items: { $ref: "#/components/schemas/BulkDeleteResult" }
|
|
1613
|
+
required: [results]
|
|
1614
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1615
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1616
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1617
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1618
|
+
|
|
1619
|
+
/admin/users/{userId}:
|
|
1620
|
+
get:
|
|
1621
|
+
tags: ["Admin: users"]
|
|
1622
|
+
summary: One user with all their access
|
|
1623
|
+
operationId: adminGetUser
|
|
1624
|
+
description: The listing caps each user's `roles` and `resources` at 50 entries (`roleCount` / `resourceCount` carry the totals); this returns every entry for one user.
|
|
1625
|
+
parameters:
|
|
1626
|
+
- $ref: "#/components/parameters/userId"
|
|
1627
|
+
responses:
|
|
1628
|
+
"200":
|
|
1629
|
+
description: The user.
|
|
1630
|
+
content:
|
|
1631
|
+
application/json:
|
|
1632
|
+
schema:
|
|
1633
|
+
type: object
|
|
1634
|
+
properties:
|
|
1635
|
+
user: { $ref: "#/components/schemas/User" }
|
|
1636
|
+
required: [user]
|
|
1637
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1638
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1639
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1640
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1641
|
+
patch:
|
|
1642
|
+
tags: ["Admin: users"]
|
|
1643
|
+
summary: Update a user
|
|
1644
|
+
operationId: adminUpdateUser
|
|
1645
|
+
description: Change the email and/or `admins`-group membership. Removing the last admin is refused (`409`).
|
|
1646
|
+
parameters:
|
|
1647
|
+
- $ref: "#/components/parameters/userId"
|
|
1648
|
+
requestBody:
|
|
1649
|
+
required: true
|
|
1650
|
+
content:
|
|
1651
|
+
application/json:
|
|
1652
|
+
schema:
|
|
1653
|
+
type: object
|
|
1654
|
+
description: At least one field.
|
|
1655
|
+
properties:
|
|
1656
|
+
email: { type: string, format: email }
|
|
1657
|
+
admin: { type: boolean }
|
|
1658
|
+
example: { admin: true }
|
|
1659
|
+
responses:
|
|
1660
|
+
"204": { description: Updated. }
|
|
1661
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1662
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1663
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1664
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1665
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1666
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1667
|
+
delete:
|
|
1668
|
+
tags: ["Admin: users"]
|
|
1669
|
+
summary: Delete a user
|
|
1670
|
+
operationId: adminDeleteUser
|
|
1671
|
+
description: "**Cascades**: grants, group memberships, preferences and access requests go too."
|
|
1672
|
+
parameters:
|
|
1673
|
+
- $ref: "#/components/parameters/userId"
|
|
1674
|
+
responses:
|
|
1675
|
+
"204": { description: Deleted. }
|
|
1676
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1677
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1678
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1679
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1680
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1681
|
+
|
|
1682
|
+
/admin/users/{userId}/grants:
|
|
1683
|
+
get:
|
|
1684
|
+
tags: ["Admin: users"]
|
|
1685
|
+
summary: A user's role grants
|
|
1686
|
+
operationId: adminListUserGrants
|
|
1687
|
+
description: Everything the user holds, direct and via groups (audit view). Works for service users too.
|
|
1688
|
+
parameters:
|
|
1689
|
+
- $ref: "#/components/parameters/userId"
|
|
1690
|
+
responses:
|
|
1691
|
+
"200":
|
|
1692
|
+
description: Grants.
|
|
1693
|
+
content:
|
|
1694
|
+
application/json:
|
|
1695
|
+
schema:
|
|
1696
|
+
type: object
|
|
1697
|
+
properties:
|
|
1698
|
+
grants:
|
|
1699
|
+
type: array
|
|
1700
|
+
items: { $ref: "#/components/schemas/UserGrant" }
|
|
1701
|
+
required: [grants]
|
|
1702
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1703
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1704
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1705
|
+
|
|
1706
|
+
/admin/users/{userId}/resource-grants:
|
|
1707
|
+
get:
|
|
1708
|
+
tags: ["Admin: users"]
|
|
1709
|
+
summary: A user's resource grants
|
|
1710
|
+
operationId: adminListUserResourceGrants
|
|
1711
|
+
parameters:
|
|
1712
|
+
- $ref: "#/components/parameters/userId"
|
|
1713
|
+
responses:
|
|
1714
|
+
"200":
|
|
1715
|
+
description: Resource grants with resolved names.
|
|
1716
|
+
content:
|
|
1717
|
+
application/json:
|
|
1718
|
+
schema:
|
|
1719
|
+
type: object
|
|
1720
|
+
properties:
|
|
1721
|
+
grants:
|
|
1722
|
+
type: array
|
|
1723
|
+
items: { $ref: "#/components/schemas/UserResourceGrantNamed" }
|
|
1724
|
+
required: [grants]
|
|
1725
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1726
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1727
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1728
|
+
|
|
1729
|
+
/admin/users/{userId}/revoke-all:
|
|
1730
|
+
post:
|
|
1731
|
+
tags: ["Admin: users"]
|
|
1732
|
+
summary: Revoke everything
|
|
1733
|
+
operationId: adminRevokeAll
|
|
1734
|
+
description: Every direct role and resource grant AND every group membership of the user goes (preferences stay). Each real loss is noticed.
|
|
1735
|
+
parameters:
|
|
1736
|
+
- $ref: "#/components/parameters/userId"
|
|
1737
|
+
responses:
|
|
1738
|
+
"200":
|
|
1739
|
+
description: How many rows were removed.
|
|
1740
|
+
content:
|
|
1741
|
+
application/json:
|
|
1742
|
+
schema:
|
|
1743
|
+
type: object
|
|
1744
|
+
properties:
|
|
1745
|
+
removed: { type: integer }
|
|
1746
|
+
required: [removed]
|
|
1747
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1748
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1749
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1750
|
+
|
|
1751
|
+
/admin/users/{userId}/resend-invite:
|
|
1752
|
+
post:
|
|
1753
|
+
tags: ["Admin: users"]
|
|
1754
|
+
summary: Resend the invitation
|
|
1755
|
+
operationId: adminResendInvite
|
|
1756
|
+
description: Re-sends the invitation email with a fresh temporary password. `409` if the user already completed setup.
|
|
1757
|
+
parameters:
|
|
1758
|
+
- $ref: "#/components/parameters/userId"
|
|
1759
|
+
responses:
|
|
1760
|
+
"204": { description: Sent. }
|
|
1761
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1762
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1763
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1764
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1765
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1766
|
+
|
|
1767
|
+
/admin/users/{userId}/signup-link:
|
|
1768
|
+
post:
|
|
1769
|
+
tags: ["Admin: users"]
|
|
1770
|
+
summary: Mint a fresh sign-up link
|
|
1771
|
+
operationId: adminMintSignupLink
|
|
1772
|
+
description: A new temporary password for a user who has not set their own yet, returned as the `/login#inv=…` link (valid 7 days). It retires the previous temporary password — the emailed link and any copied one stop working. `409` once the user completed setup.
|
|
1773
|
+
parameters:
|
|
1774
|
+
- $ref: "#/components/parameters/userId"
|
|
1775
|
+
responses:
|
|
1776
|
+
"200":
|
|
1777
|
+
description: The link.
|
|
1778
|
+
content:
|
|
1779
|
+
application/json:
|
|
1780
|
+
schema:
|
|
1781
|
+
type: object
|
|
1782
|
+
properties:
|
|
1783
|
+
signupLink: { type: string }
|
|
1784
|
+
required: [signupLink]
|
|
1785
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1786
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1787
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1788
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1789
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1790
|
+
|
|
1791
|
+
/admin/users/{userId}/reset-mfa:
|
|
1792
|
+
post:
|
|
1793
|
+
tags: ["Admin: users"]
|
|
1794
|
+
summary: Reset MFA
|
|
1795
|
+
operationId: adminResetMfa
|
|
1796
|
+
description: Lost-authenticator recovery — TOTP off, the user signs in with password alone again and can re-enrol. No-op if never enrolled.
|
|
1797
|
+
parameters:
|
|
1798
|
+
- $ref: "#/components/parameters/userId"
|
|
1799
|
+
responses:
|
|
1800
|
+
"204": { description: Reset. }
|
|
1801
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1802
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1803
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1804
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1805
|
+
|
|
1806
|
+
/admin/service-users:
|
|
1807
|
+
get:
|
|
1808
|
+
tags: ["Admin: service users"]
|
|
1809
|
+
summary: List service users
|
|
1810
|
+
operationId: adminListServiceUsers
|
|
1811
|
+
responses:
|
|
1812
|
+
"200":
|
|
1813
|
+
description: Service users with their role grants.
|
|
1814
|
+
content:
|
|
1815
|
+
application/json:
|
|
1816
|
+
schema:
|
|
1817
|
+
type: object
|
|
1818
|
+
properties:
|
|
1819
|
+
serviceUsers:
|
|
1820
|
+
type: array
|
|
1821
|
+
items: { $ref: "#/components/schemas/ServiceUser" }
|
|
1822
|
+
required: [serviceUsers]
|
|
1823
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1824
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1825
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1826
|
+
post:
|
|
1827
|
+
tags: ["Admin: service users"]
|
|
1828
|
+
summary: Create a service user
|
|
1829
|
+
operationId: adminCreateServiceUser
|
|
1830
|
+
description: Creates a `client_credentials` app client. The `201` body carries the `clientSecret` — **the only time it is ever returned**. Grant roles to it with the ordinary grant routes, using its `clientId` as the `userId`.
|
|
1831
|
+
requestBody:
|
|
1832
|
+
required: true
|
|
1833
|
+
content:
|
|
1834
|
+
application/json:
|
|
1835
|
+
schema:
|
|
1836
|
+
type: object
|
|
1837
|
+
properties:
|
|
1838
|
+
name: { type: string, minLength: 1, maxLength: 64, description: Unique among live service users. }
|
|
1839
|
+
required: [name]
|
|
1840
|
+
example: { name: "provisioning-app" }
|
|
1841
|
+
responses:
|
|
1842
|
+
"201":
|
|
1843
|
+
description: The service user and its secret.
|
|
1844
|
+
content:
|
|
1845
|
+
application/json:
|
|
1846
|
+
schema: { $ref: "#/components/schemas/ServiceUserWithSecret" }
|
|
1847
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1848
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1849
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1850
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1851
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1852
|
+
|
|
1853
|
+
/admin/service-users/{clientId}:
|
|
1854
|
+
delete:
|
|
1855
|
+
tags: ["Admin: service users"]
|
|
1856
|
+
summary: Delete a service user
|
|
1857
|
+
operationId: adminDeleteServiceUser
|
|
1858
|
+
description: "**Cascades**: the app client(s), every grant, and the registry row. Issued tokens stay signature-valid up to an hour but are refused on the next request."
|
|
1859
|
+
parameters:
|
|
1860
|
+
- $ref: "#/components/parameters/clientId"
|
|
1861
|
+
responses:
|
|
1862
|
+
"204": { description: Deleted. }
|
|
1863
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1864
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1865
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1866
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1867
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1868
|
+
|
|
1869
|
+
/admin/service-users/{clientId}/rotate:
|
|
1870
|
+
post:
|
|
1871
|
+
tags: ["Admin: service users"]
|
|
1872
|
+
summary: Rotate the secret
|
|
1873
|
+
operationId: adminRotateServiceUser
|
|
1874
|
+
description: Creates a replacement client + secret carrying the same grants; the previous secret keeps working until `DELETE …/previous`. `409` while a previous secret is still active. The returned `serviceUser.clientId` is the NEW id.
|
|
1875
|
+
parameters:
|
|
1876
|
+
- $ref: "#/components/parameters/clientId"
|
|
1877
|
+
responses:
|
|
1878
|
+
"200":
|
|
1879
|
+
description: The replacement and its secret (returned once).
|
|
1880
|
+
content:
|
|
1881
|
+
application/json:
|
|
1882
|
+
schema: { $ref: "#/components/schemas/ServiceUserWithSecret" }
|
|
1883
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1884
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1885
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1886
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1887
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1888
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1889
|
+
|
|
1890
|
+
/admin/service-users/{clientId}/previous:
|
|
1891
|
+
delete:
|
|
1892
|
+
tags: ["Admin: service users"]
|
|
1893
|
+
summary: Finish a rotation
|
|
1894
|
+
operationId: adminRemovePreviousSecret
|
|
1895
|
+
description: Retires the previous client (its grants and registry row go). `clientId` is the CURRENT client's id.
|
|
1896
|
+
parameters:
|
|
1897
|
+
- $ref: "#/components/parameters/clientId"
|
|
1898
|
+
responses:
|
|
1899
|
+
"204": { description: Retired. }
|
|
1900
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1901
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1902
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1903
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1904
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1905
|
+
|
|
1906
|
+
/admin/groups:
|
|
1907
|
+
get:
|
|
1908
|
+
tags: ["Admin: groups"]
|
|
1909
|
+
summary: List groups
|
|
1910
|
+
operationId: adminListGroups
|
|
1911
|
+
description: Every bundle with its roles, resources (names resolved) and members (emails resolved).
|
|
1912
|
+
responses:
|
|
1913
|
+
"200":
|
|
1914
|
+
description: Groups.
|
|
1915
|
+
content:
|
|
1916
|
+
application/json:
|
|
1917
|
+
schema:
|
|
1918
|
+
type: object
|
|
1919
|
+
properties:
|
|
1920
|
+
groups:
|
|
1921
|
+
type: array
|
|
1922
|
+
items: { $ref: "#/components/schemas/GroupView" }
|
|
1923
|
+
required: [groups]
|
|
1924
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1925
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1926
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1927
|
+
post:
|
|
1928
|
+
tags: ["Admin: groups"]
|
|
1929
|
+
summary: Create a group
|
|
1930
|
+
operationId: adminCreateGroup
|
|
1931
|
+
description: A bundle needs at least one role or resource. Names are unique (case-insensitive, `409`).
|
|
1932
|
+
requestBody:
|
|
1933
|
+
required: true
|
|
1934
|
+
content:
|
|
1935
|
+
application/json:
|
|
1936
|
+
schema: { $ref: "#/components/schemas/GroupInput" }
|
|
1937
|
+
example: { name: "Platform team", description: "Read access everywhere", roles: [{ accountNumber: "123456789012", roleName: "ReadOnly" }], resources: [] }
|
|
1938
|
+
responses:
|
|
1939
|
+
"201":
|
|
1940
|
+
description: The group (members and resources as raw ids).
|
|
1941
|
+
content:
|
|
1942
|
+
application/json:
|
|
1943
|
+
schema: { $ref: "#/components/schemas/GroupEnvelope" }
|
|
1944
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1945
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1946
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1947
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1948
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1949
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1950
|
+
|
|
1951
|
+
/admin/groups/{groupId}:
|
|
1952
|
+
get:
|
|
1953
|
+
tags: ["Admin: groups"]
|
|
1954
|
+
summary: One group with its whole bundle
|
|
1955
|
+
operationId: adminGetGroup
|
|
1956
|
+
description: The list caps each group's `roles` at 50 (`roleCount` carries the total); this returns every role, member and resource of one group.
|
|
1957
|
+
parameters:
|
|
1958
|
+
- $ref: "#/components/parameters/groupId"
|
|
1959
|
+
responses:
|
|
1960
|
+
"200":
|
|
1961
|
+
description: The group.
|
|
1962
|
+
content:
|
|
1963
|
+
application/json:
|
|
1964
|
+
schema: { $ref: "#/components/schemas/GroupEnvelope" }
|
|
1965
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1966
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1967
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1968
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1969
|
+
patch:
|
|
1970
|
+
tags: ["Admin: groups"]
|
|
1971
|
+
summary: Update a group
|
|
1972
|
+
operationId: adminUpdateGroup
|
|
1973
|
+
description: At least one field. A `roles`/`resources` change reconciles every member — added targets are granted to all, removed ones revoked unless held directly or via another group (losses are noticed).
|
|
1974
|
+
parameters:
|
|
1975
|
+
- $ref: "#/components/parameters/groupId"
|
|
1976
|
+
requestBody:
|
|
1977
|
+
required: true
|
|
1978
|
+
content:
|
|
1979
|
+
application/json:
|
|
1980
|
+
schema: { $ref: "#/components/schemas/GroupInput" }
|
|
1981
|
+
example: { roles: [{ accountNumber: "123456789012", roleName: "ReadOnly" }, { accountNumber: "123456789012", roleName: "PowerUser" }] }
|
|
1982
|
+
responses:
|
|
1983
|
+
"200":
|
|
1984
|
+
description: The updated group.
|
|
1985
|
+
content:
|
|
1986
|
+
application/json:
|
|
1987
|
+
schema: { $ref: "#/components/schemas/GroupEnvelope" }
|
|
1988
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
1989
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
1990
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
1991
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
1992
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
1993
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
1994
|
+
delete:
|
|
1995
|
+
tags: ["Admin: groups"]
|
|
1996
|
+
summary: Delete a group
|
|
1997
|
+
operationId: adminDeleteGroup
|
|
1998
|
+
description: Pulls the bundle from every member (direct and other-group access survives; losses are noticed).
|
|
1999
|
+
parameters:
|
|
2000
|
+
- $ref: "#/components/parameters/groupId"
|
|
2001
|
+
responses:
|
|
2002
|
+
"204": { description: Deleted. }
|
|
2003
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2004
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2005
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2006
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2007
|
+
|
|
2008
|
+
/admin/groups/{groupId}/roles:
|
|
2009
|
+
get:
|
|
2010
|
+
tags: ["Admin: groups"]
|
|
2011
|
+
summary: The bundle's roles, paged
|
|
2012
|
+
operationId: adminListGroupRoles
|
|
2013
|
+
description: The list contract over one group's roles (`q` matches role name, display name, account name or number; sorts `account` (default), `role`). Without `limit`, the first 50.
|
|
2014
|
+
parameters:
|
|
2015
|
+
- $ref: "#/components/parameters/groupId"
|
|
2016
|
+
- $ref: "#/components/parameters/listQ"
|
|
2017
|
+
- $ref: "#/components/parameters/listSort"
|
|
2018
|
+
- $ref: "#/components/parameters/listLimit"
|
|
2019
|
+
- $ref: "#/components/parameters/listCursor"
|
|
2020
|
+
responses:
|
|
2021
|
+
"200":
|
|
2022
|
+
description: One page of the bundle.
|
|
2023
|
+
content:
|
|
2024
|
+
application/json:
|
|
2025
|
+
schema:
|
|
2026
|
+
allOf:
|
|
2027
|
+
- $ref: "#/components/schemas/ListPage"
|
|
2028
|
+
- type: object
|
|
2029
|
+
properties:
|
|
2030
|
+
items:
|
|
2031
|
+
type: array
|
|
2032
|
+
items:
|
|
2033
|
+
type: object
|
|
2034
|
+
properties:
|
|
2035
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
2036
|
+
accountName: { type: string }
|
|
2037
|
+
roleName: { type: string }
|
|
2038
|
+
displayName: { type: string }
|
|
2039
|
+
required: [accountNumber, roleName]
|
|
2040
|
+
required: [items]
|
|
2041
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2042
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2043
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2044
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2045
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2046
|
+
post:
|
|
2047
|
+
tags: ["Admin: groups"]
|
|
2048
|
+
summary: Add one role to a group
|
|
2049
|
+
operationId: adminAddGroupRole
|
|
2050
|
+
description: |
|
|
2051
|
+
Adds a single catalogued role to the bundle — the call an account-registration pipeline makes per new account.
|
|
2052
|
+
Idempotent and race-free: the row is written only if absent, so a retry or two concurrent adds leave one row,
|
|
2053
|
+
and a role already in the bundle answers `200` with nothing changed, noticed or logged. Members who gain the
|
|
2054
|
+
role are noticed, as with a `PATCH`. Prefer this over `PATCH` with the full role list for large groups.
|
|
2055
|
+
Answers with the change, not the bundle (a 4,000-role group answers in well under a second); read the bundle
|
|
2056
|
+
with `GET /admin/groups/{groupId}` or page it with `GET …/roles`.
|
|
2057
|
+
parameters:
|
|
2058
|
+
- $ref: "#/components/parameters/groupId"
|
|
2059
|
+
requestBody:
|
|
2060
|
+
required: true
|
|
2061
|
+
content:
|
|
2062
|
+
application/json:
|
|
2063
|
+
schema: { $ref: "#/components/schemas/GroupRoleRef" }
|
|
2064
|
+
example: { accountNumber: "123456789012", roleName: "ReadOnly" }
|
|
2065
|
+
responses:
|
|
2066
|
+
"201":
|
|
2067
|
+
description: The role was added.
|
|
2068
|
+
content:
|
|
2069
|
+
application/json:
|
|
2070
|
+
schema: { $ref: "#/components/schemas/GroupRoleChange" }
|
|
2071
|
+
"200":
|
|
2072
|
+
description: The role was already in the bundle; nothing changed.
|
|
2073
|
+
content:
|
|
2074
|
+
application/json:
|
|
2075
|
+
schema: { $ref: "#/components/schemas/GroupRoleChange" }
|
|
2076
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2077
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2078
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2079
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2080
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2081
|
+
|
|
2082
|
+
/admin/groups/{groupId}/roles/bulk:
|
|
2083
|
+
post:
|
|
2084
|
+
tags: ["Admin: groups"]
|
|
2085
|
+
summary: Add every matching account's role to a group
|
|
2086
|
+
operationId: adminAddGroupRolesBulk
|
|
2087
|
+
description: |
|
|
2088
|
+
The group editor's "add by dimension": every registered account matching `filter` (dimension values, `unclassified` for
|
|
2089
|
+
accounts without one; keys AND together, values OR) and `q` (account name or number) that has a role named `roleName`
|
|
2090
|
+
goes into the bundle. Rows are written only if absent, roles already bundled are skipped, members who gain
|
|
2091
|
+
access are noticed as with a single add. One call writes at most 500 new rows and reports `remaining`; call again
|
|
2092
|
+
until it is 0. `dryRun: true` only counts. Matching is over the catalog; access is unchanged by it until the rows
|
|
2093
|
+
are written.
|
|
2094
|
+
parameters:
|
|
2095
|
+
- $ref: "#/components/parameters/groupId"
|
|
2096
|
+
requestBody:
|
|
2097
|
+
required: true
|
|
2098
|
+
content:
|
|
2099
|
+
application/json:
|
|
2100
|
+
schema:
|
|
2101
|
+
type: object
|
|
2102
|
+
properties:
|
|
2103
|
+
roleName: { type: string, minLength: 1 }
|
|
2104
|
+
filter:
|
|
2105
|
+
type: object
|
|
2106
|
+
properties:
|
|
2107
|
+
tenant: { type: array, items: { type: string } }
|
|
2108
|
+
project: { type: array, items: { type: string } }
|
|
2109
|
+
stage: { type: array, items: { type: string } }
|
|
2110
|
+
q: { type: string, description: Narrows by account name or number (every whitespace-separated token must occur). }
|
|
2111
|
+
dryRun: { type: boolean, default: false }
|
|
2112
|
+
required: [roleName]
|
|
2113
|
+
example: { roleName: "ReadOnly", filter: { tenant: ["acme"], stage: ["prod"] } }
|
|
2114
|
+
responses:
|
|
2115
|
+
"201":
|
|
2116
|
+
description: At least one role was added.
|
|
2117
|
+
content:
|
|
2118
|
+
application/json:
|
|
2119
|
+
schema: { $ref: "#/components/schemas/GroupRolesBulkResult" }
|
|
2120
|
+
"200":
|
|
2121
|
+
description: Nothing new (every match was already bundled), or the dry run's count.
|
|
2122
|
+
content:
|
|
2123
|
+
application/json:
|
|
2124
|
+
schema: { $ref: "#/components/schemas/GroupRolesBulkResult" }
|
|
2125
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2126
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2127
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2128
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2129
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2130
|
+
|
|
2131
|
+
/admin/groups/suggest:
|
|
2132
|
+
get:
|
|
2133
|
+
tags: ["Admin: groups"]
|
|
2134
|
+
summary: Groups to add a freshly registered role to
|
|
2135
|
+
operationId: adminSuggestGroups
|
|
2136
|
+
description: |
|
|
2137
|
+
Groups that already bundle a role of this name in the account's sibling accounts — same tenant and stage by the
|
|
2138
|
+
catalog's dimensions (deployments with `accountDimensions`). The role form offers them right after a role is
|
|
2139
|
+
registered; adding is the single-role `POST /admin/groups/{groupId}/roles`. Empty without dimensions or siblings;
|
|
2140
|
+
at most 10, most siblings first.
|
|
2141
|
+
parameters:
|
|
2142
|
+
- name: accountNumber
|
|
2143
|
+
in: query
|
|
2144
|
+
required: true
|
|
2145
|
+
schema: { $ref: "#/components/schemas/AccountNumber" }
|
|
2146
|
+
- name: roleName
|
|
2147
|
+
in: query
|
|
2148
|
+
required: true
|
|
2149
|
+
schema: { type: string, minLength: 1 }
|
|
2150
|
+
responses:
|
|
2151
|
+
"200":
|
|
2152
|
+
description: Suggested groups.
|
|
2153
|
+
content:
|
|
2154
|
+
application/json:
|
|
2155
|
+
schema:
|
|
2156
|
+
type: object
|
|
2157
|
+
properties:
|
|
2158
|
+
suggestions:
|
|
2159
|
+
type: array
|
|
2160
|
+
items:
|
|
2161
|
+
type: object
|
|
2162
|
+
properties:
|
|
2163
|
+
groupId: { type: string }
|
|
2164
|
+
name: { type: string }
|
|
2165
|
+
siblingAccounts: { type: integer, minimum: 1, description: Sibling accounts whose role of this name the group bundles. }
|
|
2166
|
+
required: [groupId, name, siblingAccounts]
|
|
2167
|
+
required: [suggestions]
|
|
2168
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2169
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2170
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2171
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2172
|
+
|
|
2173
|
+
/admin/groups/{groupId}/roles/{accountNumber}/{roleName}:
|
|
2174
|
+
delete:
|
|
2175
|
+
tags: ["Admin: groups"]
|
|
2176
|
+
summary: Remove one role from a group
|
|
2177
|
+
operationId: adminRemoveGroupRole
|
|
2178
|
+
description: Removes a single role from the bundle (members lose it unless held another way, and are noticed). A role not in the bundle is still `204`. The bundle's last target cannot be removed this way (`400`) — delete the group instead.
|
|
2179
|
+
parameters:
|
|
2180
|
+
- $ref: "#/components/parameters/groupId"
|
|
2181
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
2182
|
+
- $ref: "#/components/parameters/roleName"
|
|
2183
|
+
responses:
|
|
2184
|
+
"204": { description: Removed, or was not there. }
|
|
2185
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2186
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2187
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2188
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2189
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2190
|
+
|
|
2191
|
+
/admin/groups/{groupId}/members:
|
|
2192
|
+
post:
|
|
2193
|
+
tags: ["Admin: groups"]
|
|
2194
|
+
summary: Add members
|
|
2195
|
+
operationId: adminAddMembers
|
|
2196
|
+
description: Every new member inherits the whole bundle. Already-members are ignored.
|
|
2197
|
+
parameters:
|
|
2198
|
+
- $ref: "#/components/parameters/groupId"
|
|
2199
|
+
requestBody:
|
|
2200
|
+
required: true
|
|
2201
|
+
content:
|
|
2202
|
+
application/json:
|
|
2203
|
+
schema: { $ref: "#/components/schemas/UserIdList" }
|
|
2204
|
+
example: { userIds: ["1a2b3c4d-0000-4000-8000-000000000000"] }
|
|
2205
|
+
responses:
|
|
2206
|
+
"200":
|
|
2207
|
+
description: How many members were added.
|
|
2208
|
+
content:
|
|
2209
|
+
application/json:
|
|
2210
|
+
schema:
|
|
2211
|
+
type: object
|
|
2212
|
+
properties:
|
|
2213
|
+
added: { type: integer }
|
|
2214
|
+
required: [added]
|
|
2215
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2216
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2217
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2218
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2219
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2220
|
+
|
|
2221
|
+
/admin/groups/{groupId}/members/remove:
|
|
2222
|
+
post:
|
|
2223
|
+
tags: ["Admin: groups"]
|
|
2224
|
+
summary: Remove members
|
|
2225
|
+
operationId: adminRemoveMembers
|
|
2226
|
+
description: A POST because it carries a body. Only this group's access is pulled (losses are noticed).
|
|
2227
|
+
parameters:
|
|
2228
|
+
- $ref: "#/components/parameters/groupId"
|
|
2229
|
+
requestBody:
|
|
2230
|
+
required: true
|
|
2231
|
+
content:
|
|
2232
|
+
application/json:
|
|
2233
|
+
schema: { $ref: "#/components/schemas/UserIdList" }
|
|
2234
|
+
example: { userIds: ["1a2b3c4d-0000-4000-8000-000000000000"] }
|
|
2235
|
+
responses:
|
|
2236
|
+
"200":
|
|
2237
|
+
description: How many members were removed.
|
|
2238
|
+
content:
|
|
2239
|
+
application/json:
|
|
2240
|
+
schema:
|
|
2241
|
+
type: object
|
|
2242
|
+
properties:
|
|
2243
|
+
removed: { type: integer }
|
|
2244
|
+
required: [removed]
|
|
2245
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2246
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2247
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2248
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2249
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2250
|
+
|
|
2251
|
+
/admin/requests:
|
|
2252
|
+
get:
|
|
2253
|
+
tags: ["Admin: requests"]
|
|
2254
|
+
summary: Queue or history
|
|
2255
|
+
operationId: adminListRequests
|
|
2256
|
+
description: With `status`, that queue (oldest first); without it, the full history (newest first). Rows carry the requester's email, service-user name, group name and resource name where applicable.
|
|
2257
|
+
parameters:
|
|
2258
|
+
- name: status
|
|
2259
|
+
in: query
|
|
2260
|
+
schema: { type: string, enum: [PENDING, APPROVED, DENIED] }
|
|
2261
|
+
example: PENDING
|
|
2262
|
+
- name: usage
|
|
2263
|
+
in: query
|
|
2264
|
+
description: "`1` adds `usage` (the holder's role use in the review window) to pending reapprovals. Costly — only the Requests page sets it, never the bell poll."
|
|
2265
|
+
schema: { type: string, enum: ["1"] }
|
|
2266
|
+
responses:
|
|
2267
|
+
"200":
|
|
2268
|
+
description: Requests.
|
|
2269
|
+
content:
|
|
2270
|
+
application/json:
|
|
2271
|
+
schema:
|
|
2272
|
+
type: object
|
|
2273
|
+
properties:
|
|
2274
|
+
requests:
|
|
2275
|
+
type: array
|
|
2276
|
+
items: { $ref: "#/components/schemas/AccessRequestAdminView" }
|
|
2277
|
+
required: [requests]
|
|
2278
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2279
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2280
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2281
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2282
|
+
|
|
2283
|
+
/admin/requests/{requestId}/approve:
|
|
2284
|
+
post:
|
|
2285
|
+
tags: ["Admin: requests"]
|
|
2286
|
+
summary: Approve
|
|
2287
|
+
operationId: adminApproveRequest
|
|
2288
|
+
description: Approves **and grants** (a role, a resource, or — for reviews — confirms the admin/service user/group). The approver's `durationHours` is final, overriding what was requested. `409` if another admin already decided.
|
|
2289
|
+
parameters:
|
|
2290
|
+
- $ref: "#/components/parameters/requestId"
|
|
2291
|
+
requestBody:
|
|
2292
|
+
content:
|
|
2293
|
+
application/json:
|
|
2294
|
+
schema:
|
|
2295
|
+
type: object
|
|
2296
|
+
properties:
|
|
2297
|
+
note: { type: string, maxLength: 500, description: Shown to the requester with the decision. }
|
|
2298
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
2299
|
+
example: { note: "Approved for the incident.", durationHours: 24 }
|
|
2300
|
+
responses:
|
|
2301
|
+
"200":
|
|
2302
|
+
description: The decided request.
|
|
2303
|
+
content:
|
|
2304
|
+
application/json:
|
|
2305
|
+
schema: { $ref: "#/components/schemas/RequestEnvelope" }
|
|
2306
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2307
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2308
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2309
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2310
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
2311
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2312
|
+
|
|
2313
|
+
/admin/requests/{requestId}/deny:
|
|
2314
|
+
post:
|
|
2315
|
+
tags: ["Admin: requests"]
|
|
2316
|
+
summary: Deny
|
|
2317
|
+
operationId: adminDenyRequest
|
|
2318
|
+
description: Grants nothing. For a reapproval/review, denying **ends** the standing access under review (losses are noticed). `409` if already decided.
|
|
2319
|
+
parameters:
|
|
2320
|
+
- $ref: "#/components/parameters/requestId"
|
|
2321
|
+
requestBody:
|
|
2322
|
+
content:
|
|
2323
|
+
application/json:
|
|
2324
|
+
schema:
|
|
2325
|
+
type: object
|
|
2326
|
+
properties:
|
|
2327
|
+
note: { type: string, maxLength: 500 }
|
|
2328
|
+
example: { note: "Not needed for this role." }
|
|
2329
|
+
responses:
|
|
2330
|
+
"200":
|
|
2331
|
+
description: The decided request.
|
|
2332
|
+
content:
|
|
2333
|
+
application/json:
|
|
2334
|
+
schema: { $ref: "#/components/schemas/RequestEnvelope" }
|
|
2335
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2336
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2337
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2338
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2339
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
2340
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2341
|
+
|
|
2342
|
+
/admin/resources:
|
|
2343
|
+
get:
|
|
2344
|
+
tags: ["Admin: resources"]
|
|
2345
|
+
summary: List resources
|
|
2346
|
+
operationId: adminListResources
|
|
2347
|
+
description: The private-network resource catalog with connection details.
|
|
2348
|
+
responses:
|
|
2349
|
+
"200":
|
|
2350
|
+
description: Resources, sorted by name.
|
|
2351
|
+
content:
|
|
2352
|
+
application/json:
|
|
2353
|
+
schema:
|
|
2354
|
+
type: object
|
|
2355
|
+
properties:
|
|
2356
|
+
resources:
|
|
2357
|
+
type: array
|
|
2358
|
+
items: { $ref: "#/components/schemas/Resource" }
|
|
2359
|
+
required: [resources]
|
|
2360
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2361
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2362
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2363
|
+
post:
|
|
2364
|
+
tags: ["Admin: resources"]
|
|
2365
|
+
summary: Register a resource
|
|
2366
|
+
operationId: adminCreateResource
|
|
2367
|
+
description: A resource is reachable only through a site, so this is `501` on deployments without a private network. `cidr` accepts a bare IP or a /16–/32 CIDR. The account must be catalogued (`404`).
|
|
2368
|
+
requestBody:
|
|
2369
|
+
required: true
|
|
2370
|
+
content:
|
|
2371
|
+
application/json:
|
|
2372
|
+
schema: { $ref: "#/components/schemas/ResourceCreate" }
|
|
2373
|
+
example: { accountNumber: "123456789012", name: "Staging database", type: DATABASE, cidr: "10.0.1.25/32", ports: [5432], dnsName: "staging-db.internal", securityGroupId: "sg-0123456789abcdef0", description: "Postgres 16" }
|
|
2374
|
+
responses:
|
|
2375
|
+
"201":
|
|
2376
|
+
description: The resource.
|
|
2377
|
+
content:
|
|
2378
|
+
application/json:
|
|
2379
|
+
schema: { $ref: "#/components/schemas/ResourceEnvelope" }
|
|
2380
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2381
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2382
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2383
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2384
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
2385
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2386
|
+
|
|
2387
|
+
/admin/resources/status:
|
|
2388
|
+
get:
|
|
2389
|
+
tags: ["Admin: network"]
|
|
2390
|
+
summary: Reconciler status
|
|
2391
|
+
operationId: adminReconcilerStatus
|
|
2392
|
+
description: The grants→ACL reconciler's last-pass summary — per-resource reachability verdicts, connector freshness, rule counts.
|
|
2393
|
+
responses:
|
|
2394
|
+
"200":
|
|
2395
|
+
description: Status.
|
|
2396
|
+
content:
|
|
2397
|
+
application/json:
|
|
2398
|
+
schema: { $ref: "#/components/schemas/ReconcilerStatus" }
|
|
2399
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2400
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2401
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2402
|
+
|
|
2403
|
+
/admin/resources/{resourceId}:
|
|
2404
|
+
patch:
|
|
2405
|
+
tags: ["Admin: resources"]
|
|
2406
|
+
summary: Update a resource
|
|
2407
|
+
operationId: adminUpdateResource
|
|
2408
|
+
description: At least one field. `accountNumber` is immutable (it IS the connector binding) — moving a resource means recreating it.
|
|
2409
|
+
parameters:
|
|
2410
|
+
- $ref: "#/components/parameters/resourceId"
|
|
2411
|
+
requestBody:
|
|
2412
|
+
required: true
|
|
2413
|
+
content:
|
|
2414
|
+
application/json:
|
|
2415
|
+
schema: { $ref: "#/components/schemas/ResourcePatch" }
|
|
2416
|
+
example: { ports: [5432, 5433], description: "Postgres 16 + pgbouncer" }
|
|
2417
|
+
responses:
|
|
2418
|
+
"200":
|
|
2419
|
+
description: The updated resource.
|
|
2420
|
+
content:
|
|
2421
|
+
application/json:
|
|
2422
|
+
schema: { $ref: "#/components/schemas/ResourceEnvelope" }
|
|
2423
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2424
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2425
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2426
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2427
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2428
|
+
delete:
|
|
2429
|
+
tags: ["Admin: resources"]
|
|
2430
|
+
summary: Remove a resource
|
|
2431
|
+
operationId: adminDeleteResource
|
|
2432
|
+
description: "**Cascades**: every grant on the resource is revoked (losses are noticed), groups bundling it drop it (a group left empty is removed), and its open requests and reviews are denied with the reason. Grants go before the catalog row, so a call that failed halfway can be repeated."
|
|
2433
|
+
parameters:
|
|
2434
|
+
- $ref: "#/components/parameters/resourceId"
|
|
2435
|
+
responses:
|
|
2436
|
+
"204": { description: Removed. }
|
|
2437
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2438
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2439
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2440
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2441
|
+
|
|
2442
|
+
/admin/resources/{resourceId}/grants:
|
|
2443
|
+
get:
|
|
2444
|
+
tags: ["Admin: resources"]
|
|
2445
|
+
summary: Who can reach this resource
|
|
2446
|
+
operationId: adminListResourceGrantees
|
|
2447
|
+
parameters:
|
|
2448
|
+
- $ref: "#/components/parameters/resourceId"
|
|
2449
|
+
responses:
|
|
2450
|
+
"200":
|
|
2451
|
+
description: Holders with emails resolved.
|
|
2452
|
+
content:
|
|
2453
|
+
application/json:
|
|
2454
|
+
schema:
|
|
2455
|
+
type: object
|
|
2456
|
+
properties:
|
|
2457
|
+
grantees:
|
|
2458
|
+
type: array
|
|
2459
|
+
items: { $ref: "#/components/schemas/ResourceGrantee" }
|
|
2460
|
+
required: [grantees]
|
|
2461
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2462
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2463
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2464
|
+
|
|
2465
|
+
/admin/resources/{resourceId}/grants/{userId}:
|
|
2466
|
+
put:
|
|
2467
|
+
tags: ["Admin: resources"]
|
|
2468
|
+
summary: Grant a resource
|
|
2469
|
+
operationId: adminAssignResource
|
|
2470
|
+
description: Idempotent; re-granting overwrites the expiry. A long-term grant is never downgraded. Reachability follows on the reconciler's next pass (≤ 5 min).
|
|
2471
|
+
parameters:
|
|
2472
|
+
- $ref: "#/components/parameters/resourceId"
|
|
2473
|
+
- $ref: "#/components/parameters/userId"
|
|
2474
|
+
requestBody:
|
|
2475
|
+
content:
|
|
2476
|
+
application/json:
|
|
2477
|
+
schema:
|
|
2478
|
+
type: object
|
|
2479
|
+
properties:
|
|
2480
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
2481
|
+
example: { durationHours: 72 }
|
|
2482
|
+
responses:
|
|
2483
|
+
"200":
|
|
2484
|
+
description: The grant.
|
|
2485
|
+
content:
|
|
2486
|
+
application/json:
|
|
2487
|
+
schema:
|
|
2488
|
+
type: object
|
|
2489
|
+
properties:
|
|
2490
|
+
grant: { $ref: "#/components/schemas/UserResourceGrant" }
|
|
2491
|
+
required: [grant]
|
|
2492
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2493
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2494
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2495
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2496
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2497
|
+
delete:
|
|
2498
|
+
tags: ["Admin: resources"]
|
|
2499
|
+
summary: Revoke a resource
|
|
2500
|
+
operationId: adminRevokeResource
|
|
2501
|
+
parameters:
|
|
2502
|
+
- $ref: "#/components/parameters/resourceId"
|
|
2503
|
+
- $ref: "#/components/parameters/userId"
|
|
2504
|
+
responses:
|
|
2505
|
+
"204": { description: Revoked. }
|
|
2506
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2507
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2508
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2509
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2510
|
+
|
|
2511
|
+
/admin/network:
|
|
2512
|
+
get:
|
|
2513
|
+
tags: ["Admin: network"]
|
|
2514
|
+
summary: Network topology
|
|
2515
|
+
operationId: adminNetworkTopology
|
|
2516
|
+
description: Everything the admin Network map needs — the full site config (split DNS and declared VPCs included) plus the reconciler's last-pass status.
|
|
2517
|
+
responses:
|
|
2518
|
+
"200":
|
|
2519
|
+
description: Sites and status.
|
|
2520
|
+
content:
|
|
2521
|
+
application/json:
|
|
2522
|
+
schema:
|
|
2523
|
+
type: object
|
|
2524
|
+
properties:
|
|
2525
|
+
sites:
|
|
2526
|
+
type: array
|
|
2527
|
+
items: { $ref: "#/components/schemas/NetworkSite" }
|
|
2528
|
+
status: { $ref: "#/components/schemas/ReconcilerStatus" }
|
|
2529
|
+
required: [sites, status]
|
|
2530
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2531
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2532
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2533
|
+
|
|
2534
|
+
/admin/network/shares:
|
|
2535
|
+
get:
|
|
2536
|
+
tags: ["Admin: network"]
|
|
2537
|
+
summary: Every live dev share
|
|
2538
|
+
operationId: adminListDevShares
|
|
2539
|
+
description: Owner, port, site, expiry and grantees of every unexpired share; stop one with `DELETE /network/shares/{shareId}` (admins may).
|
|
2540
|
+
responses:
|
|
2541
|
+
"200":
|
|
2542
|
+
description: Soonest expiry first.
|
|
2543
|
+
content:
|
|
2544
|
+
application/json:
|
|
2545
|
+
schema:
|
|
2546
|
+
type: object
|
|
2547
|
+
properties:
|
|
2548
|
+
shares: { type: array, items: { $ref: "#/components/schemas/DevShare" } }
|
|
2549
|
+
required: [shares]
|
|
2550
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2551
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2552
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
2553
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2554
|
+
|
|
2555
|
+
/admin/network/sync:
|
|
2556
|
+
post:
|
|
2557
|
+
tags: ["Admin: network"]
|
|
2558
|
+
summary: Sync now
|
|
2559
|
+
operationId: adminNetworkSync
|
|
2560
|
+
description: Kicks the grants→ACL reconciler ahead of its 5-minute schedule. Fire-and-forget — re-read `GET /admin/resources/status` for the outcome.
|
|
2561
|
+
responses:
|
|
2562
|
+
"202":
|
|
2563
|
+
description: Sync requested.
|
|
2564
|
+
content:
|
|
2565
|
+
application/json:
|
|
2566
|
+
schema: { $ref: "#/components/schemas/Message" }
|
|
2567
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2568
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2569
|
+
"501": { $ref: "#/components/responses/NotDeployed" }
|
|
2570
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2571
|
+
|
|
2572
|
+
/admin/audit:
|
|
2573
|
+
get:
|
|
2574
|
+
tags: ["Admin: audit"]
|
|
2575
|
+
summary: The activity log
|
|
2576
|
+
operationId: adminListAudit
|
|
2577
|
+
description: |
|
|
2578
|
+
Every recorded action, newest first: who did it, what, to whom or what, the outcome and why. The window is
|
|
2579
|
+
`from`/`to` (a span of at most 90 days, anywhere inside the retention), or `days` back from now (default 7).
|
|
2580
|
+
A full page (`limit`, default 200, max 1000) reports `nextBefore`; pass it back as `before` for older rows.
|
|
2581
|
+
`user` (the person, group or service user an action was about) returns that subject's own trail. Per-user
|
|
2582
|
+
derived rows (`derived: true`, written by the access diff for group, cascade and bulk changes) are hidden
|
|
2583
|
+
unless `derived=true`. Names are joined from the directory,
|
|
2584
|
+
the group list and the resource catalog; a caller deleted since carries `deleted: true` and their snapshot name.
|
|
2585
|
+
Rows written before the general log (vend-only) are returned in the same shape.
|
|
2586
|
+
parameters:
|
|
2587
|
+
- name: from
|
|
2588
|
+
in: query
|
|
2589
|
+
schema: { type: string, format: date-time }
|
|
2590
|
+
- name: to
|
|
2591
|
+
in: query
|
|
2592
|
+
schema: { type: string, format: date-time }
|
|
2593
|
+
- name: before
|
|
2594
|
+
in: query
|
|
2595
|
+
description: Upper bound for the next page, inclusive (the previous page's `nextBefore`); send `skip` with it.
|
|
2596
|
+
schema: { type: string, format: date-time }
|
|
2597
|
+
- name: skip
|
|
2598
|
+
in: query
|
|
2599
|
+
description: Comma-separated event ids already held whose `at` equals `before` — rows written in one batch can share an instant, so the cursor is inclusive and these are left out.
|
|
2600
|
+
schema: { type: string }
|
|
2601
|
+
- name: days
|
|
2602
|
+
in: query
|
|
2603
|
+
description: Shorthand for `from` = now minus this many days.
|
|
2604
|
+
schema: { type: integer, minimum: 1, maximum: 90 }
|
|
2605
|
+
example: 7
|
|
2606
|
+
- name: limit
|
|
2607
|
+
in: query
|
|
2608
|
+
schema: { type: integer, minimum: 1, maximum: 1000, default: 200 }
|
|
2609
|
+
- name: user
|
|
2610
|
+
in: query
|
|
2611
|
+
description: Subject ids, comma-separated (Cognito subs, group ids or service-user client ids; at most 10 — one indexed query each, merged). `userId` is accepted as an alias.
|
|
2612
|
+
schema: { type: string }
|
|
2613
|
+
- name: userId
|
|
2614
|
+
in: query
|
|
2615
|
+
deprecated: true
|
|
2616
|
+
schema: { type: string }
|
|
2617
|
+
- name: actor
|
|
2618
|
+
in: query
|
|
2619
|
+
description: Who did it, comma-separated (subs, client ids, or `system:<job>`; at most 10). Rows from before the general log are found by their caller; VPN session rows (`vpn.connect`/`vpn.disconnect`) by the person who connected, never by `system:reconciler`.
|
|
2620
|
+
schema: { type: string }
|
|
2621
|
+
- name: category
|
|
2622
|
+
in: query
|
|
2623
|
+
description: Comma-separated.
|
|
2624
|
+
schema: { type: string, example: "access,request" }
|
|
2625
|
+
- name: outcome
|
|
2626
|
+
in: query
|
|
2627
|
+
description: Comma-separated.
|
|
2628
|
+
schema: { type: string, example: "DENIED,FAILED" }
|
|
2629
|
+
- name: account
|
|
2630
|
+
in: query
|
|
2631
|
+
description: Comma-separated account numbers.
|
|
2632
|
+
schema: { type: string }
|
|
2633
|
+
- name: group
|
|
2634
|
+
in: query
|
|
2635
|
+
description: "Comma-separated group ids — everything about each group: its own rows, rows through it, rows where it is the subject."
|
|
2636
|
+
schema: { type: string }
|
|
2637
|
+
- name: target
|
|
2638
|
+
in: query
|
|
2639
|
+
description: Exact targets (`role#<account>#<name>`, `resource#<id>`, …). Repeat the parameter for several; a value is never split (a role name may contain a comma).
|
|
2640
|
+
schema:
|
|
2641
|
+
type: array
|
|
2642
|
+
items: { type: string }
|
|
2643
|
+
style: form
|
|
2644
|
+
explode: true
|
|
2645
|
+
- name: derived
|
|
2646
|
+
in: query
|
|
2647
|
+
schema: { type: boolean, default: false }
|
|
2648
|
+
responses:
|
|
2649
|
+
"200":
|
|
2650
|
+
description: One page of the log.
|
|
2651
|
+
content:
|
|
2652
|
+
application/json:
|
|
2653
|
+
schema: { $ref: "#/components/schemas/ActivityPage" }
|
|
2654
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2655
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2656
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2657
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2658
|
+
|
|
2659
|
+
/admin/access-report/jobs:
|
|
2660
|
+
post:
|
|
2661
|
+
tags: ["Admin: audit"]
|
|
2662
|
+
summary: Build the access report in the background
|
|
2663
|
+
operationId: adminStartAccessReport
|
|
2664
|
+
description: Starts the report as a job (a large catalog produces more rows than one API call may carry) and answers at once with its id. Poll `GET /admin/access-report/jobs/{jobId}` until `status` is `done`, then download from `url` (valid 15 minutes). Only the admin who started a job can read it.
|
|
2665
|
+
responses:
|
|
2666
|
+
"202":
|
|
2667
|
+
description: The job, running.
|
|
2668
|
+
content:
|
|
2669
|
+
application/json:
|
|
2670
|
+
schema:
|
|
2671
|
+
type: object
|
|
2672
|
+
properties:
|
|
2673
|
+
job: { $ref: "#/components/schemas/ReportJob" }
|
|
2674
|
+
required: [job]
|
|
2675
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2676
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2677
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2678
|
+
|
|
2679
|
+
/admin/access-report/jobs/{jobId}:
|
|
2680
|
+
get:
|
|
2681
|
+
tags: ["Admin: audit"]
|
|
2682
|
+
summary: An access report job
|
|
2683
|
+
operationId: adminGetAccessReportJob
|
|
2684
|
+
parameters:
|
|
2685
|
+
- name: jobId
|
|
2686
|
+
in: path
|
|
2687
|
+
required: true
|
|
2688
|
+
schema: { type: string, format: uuid }
|
|
2689
|
+
responses:
|
|
2690
|
+
"200":
|
|
2691
|
+
description: The job; with `url` once done.
|
|
2692
|
+
content:
|
|
2693
|
+
application/json:
|
|
2694
|
+
schema:
|
|
2695
|
+
type: object
|
|
2696
|
+
properties:
|
|
2697
|
+
job: { $ref: "#/components/schemas/ReportJob" }
|
|
2698
|
+
required: [job]
|
|
2699
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2700
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2701
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2702
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2703
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2704
|
+
|
|
2705
|
+
/admin/access-report:
|
|
2706
|
+
get:
|
|
2707
|
+
tags: ["Admin: audit"]
|
|
2708
|
+
summary: Who can reach what right now (CSV)
|
|
2709
|
+
operationId: adminAccessReport
|
|
2710
|
+
description: One row per person (or service user) and target they hold this instant — how (direct, or through which groups), who granted it, when, until when, and when they were last seen. The log explains how each row came to be; this is the state. Built inline, so it fits only while the result stays under API Gateway's 6 MB; the app uses the job endpoints above.
|
|
2711
|
+
responses:
|
|
2712
|
+
"200":
|
|
2713
|
+
description: "A CSV download (`Content-Disposition: attachment`), UTF-8 with BOM."
|
|
2714
|
+
content:
|
|
2715
|
+
text/csv:
|
|
2716
|
+
schema: { type: string }
|
|
2717
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2718
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2719
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2720
|
+
|
|
2721
|
+
/plugins:
|
|
2722
|
+
get:
|
|
2723
|
+
tags: [Plugins]
|
|
2724
|
+
summary: Plugins this caller may open
|
|
2725
|
+
operationId: listPlugins
|
|
2726
|
+
description: >-
|
|
2727
|
+
Metadata only, never plugin code. A plugin appears only where the caller has an available capability,
|
|
2728
|
+
and a UI entry only where its own permission is available in at least one listed account. Account names
|
|
2729
|
+
come from the Accounts catalog, so a caller holding nothing but a plugin grant still sees the account.
|
|
2730
|
+
The feature being off, or no plugin being registered, is an empty list — never an error, and never
|
|
2731
|
+
cached across callers.
|
|
2732
|
+
responses:
|
|
2733
|
+
"200":
|
|
2734
|
+
description: The caller's plugins.
|
|
2735
|
+
content:
|
|
2736
|
+
application/json:
|
|
2737
|
+
schema: { $ref: "#/components/schemas/PluginDiscovery" }
|
|
2738
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2739
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2740
|
+
|
|
2741
|
+
/plugins/expiry:
|
|
2742
|
+
get:
|
|
2743
|
+
tags: [Plugins]
|
|
2744
|
+
summary: My plugin expiry notices
|
|
2745
|
+
operationId: listPluginExpiryNotices
|
|
2746
|
+
description: Temporary plugin permissions nearing / past their end, named for the bell (a removed plugin keeps its label; an account without a name shows its number).
|
|
2747
|
+
responses:
|
|
2748
|
+
"200":
|
|
2749
|
+
description: Soonest expiry first; most recently expired first.
|
|
2750
|
+
content:
|
|
2751
|
+
application/json:
|
|
2752
|
+
schema:
|
|
2753
|
+
type: object
|
|
2754
|
+
properties:
|
|
2755
|
+
expiring:
|
|
2756
|
+
type: array
|
|
2757
|
+
items: { $ref: "#/components/schemas/PluginExpiryNotice" }
|
|
2758
|
+
expired:
|
|
2759
|
+
type: array
|
|
2760
|
+
items: { $ref: "#/components/schemas/PluginExpiryNotice" }
|
|
2761
|
+
required: [expiring, expired]
|
|
2762
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2763
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2764
|
+
|
|
2765
|
+
/plugins/expiry/seen:
|
|
2766
|
+
post:
|
|
2767
|
+
tags: [Plugins]
|
|
2768
|
+
summary: Acknowledge plugin expiry notices
|
|
2769
|
+
operationId: markPluginExpiryNoticesSeen
|
|
2770
|
+
responses:
|
|
2771
|
+
"200":
|
|
2772
|
+
description: How many notices were newly marked seen.
|
|
2773
|
+
content:
|
|
2774
|
+
application/json:
|
|
2775
|
+
schema: { $ref: "#/components/schemas/Cleared" }
|
|
2776
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2777
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2778
|
+
|
|
2779
|
+
/admin/plugins:
|
|
2780
|
+
get:
|
|
2781
|
+
tags: ["Admin: plugins"]
|
|
2782
|
+
summary: Every plugin definition
|
|
2783
|
+
operationId: adminListPlugins
|
|
2784
|
+
description: >-
|
|
2785
|
+
The grant editor's view: installed, disabled and unavailable definitions, plus tombstones still worth
|
|
2786
|
+
labelling for grants that outlived them. Independent of the admin's own plugin grants, so a binding
|
|
2787
|
+
nobody holds yet is still assignable. Handler internals and credentials are never included.
|
|
2788
|
+
responses:
|
|
2789
|
+
"200":
|
|
2790
|
+
description: The catalog.
|
|
2791
|
+
content:
|
|
2792
|
+
application/json:
|
|
2793
|
+
schema: { $ref: "#/components/schemas/PluginAdminCatalog" }
|
|
2794
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2795
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2796
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2797
|
+
|
|
2798
|
+
/admin/users/{userId}/plugin-grants:
|
|
2799
|
+
get:
|
|
2800
|
+
tags: ["Admin: plugins"]
|
|
2801
|
+
summary: A user's plugin access
|
|
2802
|
+
operationId: adminListUserPluginGrants
|
|
2803
|
+
description: >-
|
|
2804
|
+
Their stored plugin rows (expired and dormant included, so the editor can show why one does nothing)
|
|
2805
|
+
and the capabilities those add up to, direct and through groups. A sibling of the resource-grants
|
|
2806
|
+
view: one call covers every plugin, so the user page never sweeps per-plugin endpoints.
|
|
2807
|
+
parameters:
|
|
2808
|
+
- $ref: "#/components/parameters/userId"
|
|
2809
|
+
responses:
|
|
2810
|
+
"200":
|
|
2811
|
+
description: Stored assignments and effective capabilities.
|
|
2812
|
+
content:
|
|
2813
|
+
application/json:
|
|
2814
|
+
schema: { $ref: "#/components/schemas/UserPluginAccess" }
|
|
2815
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2816
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2817
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2818
|
+
|
|
2819
|
+
/admin/groups/{groupId}/plugin-grants:
|
|
2820
|
+
get:
|
|
2821
|
+
tags: ["Admin: plugins"]
|
|
2822
|
+
summary: A group's plugin assignments
|
|
2823
|
+
operationId: adminListGroupPluginGrants
|
|
2824
|
+
description: >-
|
|
2825
|
+
The bindings this group hands its members, each marked with whether it can authorize anything right
|
|
2826
|
+
now. The groups list carries the same bindings as bare references; this adds the availability the
|
|
2827
|
+
editor needs to show a dormant assignment as dormant and still offer to revoke it.
|
|
2828
|
+
parameters:
|
|
2829
|
+
- $ref: "#/components/parameters/groupId"
|
|
2830
|
+
responses:
|
|
2831
|
+
"200":
|
|
2832
|
+
description: The group's assignments.
|
|
2833
|
+
content:
|
|
2834
|
+
application/json:
|
|
2835
|
+
schema:
|
|
2836
|
+
type: object
|
|
2837
|
+
properties:
|
|
2838
|
+
assignments:
|
|
2839
|
+
type: array
|
|
2840
|
+
items: { $ref: "#/components/schemas/PluginAssignment" }
|
|
2841
|
+
required: [assignments]
|
|
2842
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2843
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2844
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2845
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2846
|
+
|
|
2847
|
+
/admin/plugins/{pluginId}/accounts/{accountNumber}/grants:
|
|
2848
|
+
get:
|
|
2849
|
+
tags: ["Admin: plugins"]
|
|
2850
|
+
summary: Who holds this plugin binding
|
|
2851
|
+
operationId: adminListPluginGrants
|
|
2852
|
+
description: Stored assignments (users and groups, expired rows included) and the effective holders with provenance.
|
|
2853
|
+
parameters:
|
|
2854
|
+
- $ref: "#/components/parameters/pluginId"
|
|
2855
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
2856
|
+
responses:
|
|
2857
|
+
"200":
|
|
2858
|
+
description: Assignments and holders.
|
|
2859
|
+
content:
|
|
2860
|
+
application/json:
|
|
2861
|
+
schema:
|
|
2862
|
+
type: object
|
|
2863
|
+
properties:
|
|
2864
|
+
assignments:
|
|
2865
|
+
type: array
|
|
2866
|
+
items: { $ref: "#/components/schemas/PluginAssignment" }
|
|
2867
|
+
holders:
|
|
2868
|
+
type: array
|
|
2869
|
+
items: { $ref: "#/components/schemas/PluginHolder" }
|
|
2870
|
+
required: [assignments, holders]
|
|
2871
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2872
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2873
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2874
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2875
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2876
|
+
put:
|
|
2877
|
+
tags: ["Admin: plugins"]
|
|
2878
|
+
summary: Assign plugin access
|
|
2879
|
+
operationId: adminAssignPlugin
|
|
2880
|
+
description: >-
|
|
2881
|
+
Idempotent; re-assigning rewrites the row (the extend path) and never downgrades a long-term grant to
|
|
2882
|
+
a temporary one. Groups are standing, so an expiry on a group is refused. 404 for an unknown plugin,
|
|
2883
|
+
group, or user (a person in the pool or a registered service user). 409 when the plugin is installed
|
|
2884
|
+
but the binding is unavailable (disabled, removed, unsupported, or an unregistered account).
|
|
2885
|
+
parameters:
|
|
2886
|
+
- $ref: "#/components/parameters/pluginId"
|
|
2887
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
2888
|
+
requestBody:
|
|
2889
|
+
required: true
|
|
2890
|
+
content:
|
|
2891
|
+
application/json:
|
|
2892
|
+
schema:
|
|
2893
|
+
type: object
|
|
2894
|
+
properties:
|
|
2895
|
+
principal: { $ref: "#/components/schemas/PluginPrincipal" }
|
|
2896
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
2897
|
+
durationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
2898
|
+
required: [principal, permission]
|
|
2899
|
+
example: { principal: { kind: user, userId: 6f1e2d3c-0000-4000-8000-000000000001 }, permission: user }
|
|
2900
|
+
responses:
|
|
2901
|
+
"200":
|
|
2902
|
+
description: The stored assignment.
|
|
2903
|
+
content:
|
|
2904
|
+
application/json:
|
|
2905
|
+
schema:
|
|
2906
|
+
type: object
|
|
2907
|
+
properties:
|
|
2908
|
+
assignment: { $ref: "#/components/schemas/PluginAssignment" }
|
|
2909
|
+
required: [assignment]
|
|
2910
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2911
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2912
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2913
|
+
"404": { $ref: "#/components/responses/NotFound" }
|
|
2914
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
2915
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2916
|
+
delete:
|
|
2917
|
+
tags: ["Admin: plugins"]
|
|
2918
|
+
summary: Revoke plugin access
|
|
2919
|
+
operationId: adminRevokePlugin
|
|
2920
|
+
description: >-
|
|
2921
|
+
Idempotent, and deliberately unconditional: a stale row on a disabled or removed plugin stays
|
|
2922
|
+
revocable, so availability is not checked first. Holders who lose a capability are noticed.
|
|
2923
|
+
parameters:
|
|
2924
|
+
- $ref: "#/components/parameters/pluginId"
|
|
2925
|
+
- $ref: "#/components/parameters/accountNumber"
|
|
2926
|
+
requestBody:
|
|
2927
|
+
required: true
|
|
2928
|
+
content:
|
|
2929
|
+
application/json:
|
|
2930
|
+
schema:
|
|
2931
|
+
type: object
|
|
2932
|
+
properties:
|
|
2933
|
+
principal: { $ref: "#/components/schemas/PluginPrincipal" }
|
|
2934
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
2935
|
+
required: [principal, permission]
|
|
2936
|
+
example: { principal: { kind: group, groupId: platform-team }, permission: admin }
|
|
2937
|
+
responses:
|
|
2938
|
+
"204": { description: Revoked (or there was nothing to revoke — this is idempotent). }
|
|
2939
|
+
"400": { $ref: "#/components/responses/BadRequest" }
|
|
2940
|
+
"401": { $ref: "#/components/responses/Unauthorized" }
|
|
2941
|
+
"403": { $ref: "#/components/responses/Forbidden" }
|
|
2942
|
+
"404": { description: The named group does not exist. }
|
|
2943
|
+
"409": { $ref: "#/components/responses/Conflict" }
|
|
2944
|
+
"502": { $ref: "#/components/responses/Upstream" }
|
|
2945
|
+
|
|
2946
|
+
components:
|
|
2947
|
+
securitySchemes:
|
|
2948
|
+
bearerAuth:
|
|
2949
|
+
type: http
|
|
2950
|
+
scheme: bearer
|
|
2951
|
+
bearerFormat: JWT
|
|
2952
|
+
description: A Cognito ID token (humans) or a `client_credentials` access token with the `api/invoke` scope (service users).
|
|
2953
|
+
|
|
2954
|
+
parameters:
|
|
2955
|
+
accountNumber:
|
|
2956
|
+
name: accountNumber
|
|
2957
|
+
in: path
|
|
2958
|
+
required: true
|
|
2959
|
+
schema: { $ref: "#/components/schemas/AccountNumber" }
|
|
2960
|
+
roleName:
|
|
2961
|
+
name: roleName
|
|
2962
|
+
in: path
|
|
2963
|
+
required: true
|
|
2964
|
+
description: The IAM role name as catalogued (not the ARN).
|
|
2965
|
+
schema: { type: string }
|
|
2966
|
+
role:
|
|
2967
|
+
name: role
|
|
2968
|
+
in: path
|
|
2969
|
+
required: true
|
|
2970
|
+
description: The IAM role name as catalogued (not the ARN).
|
|
2971
|
+
schema: { type: string }
|
|
2972
|
+
userId:
|
|
2973
|
+
name: userId
|
|
2974
|
+
in: path
|
|
2975
|
+
required: true
|
|
2976
|
+
description: A Cognito `sub`, or a service user's client id.
|
|
2977
|
+
schema: { type: string }
|
|
2978
|
+
requestId:
|
|
2979
|
+
name: requestId
|
|
2980
|
+
in: path
|
|
2981
|
+
required: true
|
|
2982
|
+
schema: { type: string }
|
|
2983
|
+
groupId:
|
|
2984
|
+
name: groupId
|
|
2985
|
+
in: path
|
|
2986
|
+
required: true
|
|
2987
|
+
schema: { type: string }
|
|
2988
|
+
resourceId:
|
|
2989
|
+
name: resourceId
|
|
2990
|
+
in: path
|
|
2991
|
+
required: true
|
|
2992
|
+
schema: { type: string }
|
|
2993
|
+
pluginId:
|
|
2994
|
+
name: pluginId
|
|
2995
|
+
in: path
|
|
2996
|
+
required: true
|
|
2997
|
+
description: The plugin's registered id.
|
|
2998
|
+
schema: { type: string, pattern: "^[a-z][a-z0-9-]{0,63}$" }
|
|
2999
|
+
example: parameters
|
|
3000
|
+
clientId:
|
|
3001
|
+
name: clientId
|
|
3002
|
+
in: path
|
|
3003
|
+
required: true
|
|
3004
|
+
description: A Cognito app client id (lowercase alphanumerics).
|
|
3005
|
+
schema: { type: string, pattern: "^[a-z0-9]{1,128}$" }
|
|
3006
|
+
# The list contract (catalog-sized lists): pass `limit` to receive one page — `{ items, nextCursor, total,
|
|
3007
|
+
# facets }` — instead of the whole list. Pages are cut in the API from an in-memory catalog index after
|
|
3008
|
+
# access is decided, so search is substring-by-token, sorts are any listed key, totals are exact.
|
|
3009
|
+
listQ:
|
|
3010
|
+
name: q
|
|
3011
|
+
in: query
|
|
3012
|
+
description: Whitespace-separated tokens; every token must occur (case-insensitive substring) in the row's searchable text (name, number, role names).
|
|
3013
|
+
schema: { type: string }
|
|
3014
|
+
listFilter:
|
|
3015
|
+
name: filter
|
|
3016
|
+
in: query
|
|
3017
|
+
description: Facet filters, `filter[key]=a,b` (any of the listed values; keys AND together). Each route names its facet keys.
|
|
3018
|
+
style: deepObject
|
|
3019
|
+
explode: true
|
|
3020
|
+
schema:
|
|
3021
|
+
type: object
|
|
3022
|
+
additionalProperties: { type: string }
|
|
3023
|
+
listSort:
|
|
3024
|
+
name: sort
|
|
3025
|
+
in: query
|
|
3026
|
+
description: A sort key the route lists; prefix `-` for descending. Ties break on the row id.
|
|
3027
|
+
schema: { type: string }
|
|
3028
|
+
listLimit:
|
|
3029
|
+
name: limit
|
|
3030
|
+
in: query
|
|
3031
|
+
description: Page size, 1–200. Present = paged response; absent = the whole list (older clients).
|
|
3032
|
+
schema: { type: integer, minimum: 1, maximum: 200 }
|
|
3033
|
+
listCursor:
|
|
3034
|
+
name: cursor
|
|
3035
|
+
in: query
|
|
3036
|
+
description: The previous page's `nextCursor`. Opaque; tied to the same `q`/`filter`/`sort` (400 otherwise). Rows inserted or removed between pages are neither skipped nor repeated.
|
|
3037
|
+
schema: { type: string }
|
|
3038
|
+
|
|
3039
|
+
responses:
|
|
3040
|
+
BadRequest:
|
|
3041
|
+
description: Malformed input — the message says which field.
|
|
3042
|
+
content:
|
|
3043
|
+
application/json:
|
|
3044
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3045
|
+
Unauthorized:
|
|
3046
|
+
description: Missing, invalid or expired bearer token.
|
|
3047
|
+
content:
|
|
3048
|
+
application/json:
|
|
3049
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3050
|
+
Forbidden:
|
|
3051
|
+
description: Admin access required.
|
|
3052
|
+
content:
|
|
3053
|
+
application/json:
|
|
3054
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3055
|
+
NotFound:
|
|
3056
|
+
description: The addressed thing does not exist.
|
|
3057
|
+
content:
|
|
3058
|
+
application/json:
|
|
3059
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3060
|
+
Conflict:
|
|
3061
|
+
description: Already exists, still in use, or already decided.
|
|
3062
|
+
content:
|
|
3063
|
+
application/json:
|
|
3064
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3065
|
+
NotDeployed:
|
|
3066
|
+
description: The feature is not deployed on this installation.
|
|
3067
|
+
content:
|
|
3068
|
+
application/json:
|
|
3069
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3070
|
+
Upstream:
|
|
3071
|
+
description: A downstream AWS call failed (details stay in the Lambda log).
|
|
3072
|
+
content:
|
|
3073
|
+
application/json:
|
|
3074
|
+
schema: { $ref: "#/components/schemas/Error" }
|
|
3075
|
+
|
|
3076
|
+
schemas:
|
|
3077
|
+
ReportJob:
|
|
3078
|
+
type: object
|
|
3079
|
+
properties:
|
|
3080
|
+
jobId: { type: string, format: uuid }
|
|
3081
|
+
kind: { type: string, enum: [accessReport] }
|
|
3082
|
+
status: { type: string, enum: [running, done, failed] }
|
|
3083
|
+
requestedBy: { type: string }
|
|
3084
|
+
startedAt: { type: string, format: date-time }
|
|
3085
|
+
finishedAt: { type: string, format: date-time }
|
|
3086
|
+
rows: { type: integer, minimum: 0 }
|
|
3087
|
+
error: { type: string }
|
|
3088
|
+
url: { type: string, format: uri, description: Presigned download, present once `done`; valid 15 minutes. }
|
|
3089
|
+
required: [jobId, kind, status, requestedBy, startedAt]
|
|
3090
|
+
ListPage:
|
|
3091
|
+
type: object
|
|
3092
|
+
description: One page of the list contract. `items` is typed per route.
|
|
3093
|
+
properties:
|
|
3094
|
+
nextCursor: { type: string, description: Pass as `cursor` for the next page; absent on the last page. }
|
|
3095
|
+
total: { type: integer, minimum: 0, description: Rows matching `q` and the filters, across all pages. }
|
|
3096
|
+
facets:
|
|
3097
|
+
type: object
|
|
3098
|
+
description: "Per facet key: value → row count over the rows matching `q` and the OTHER facets' filters (so a filtered facet still shows its alternatives)."
|
|
3099
|
+
additionalProperties:
|
|
3100
|
+
type: object
|
|
3101
|
+
additionalProperties: { type: integer }
|
|
3102
|
+
required: [total, facets]
|
|
3103
|
+
AccountAccessPage:
|
|
3104
|
+
allOf:
|
|
3105
|
+
- $ref: "#/components/schemas/ListPage"
|
|
3106
|
+
- type: object
|
|
3107
|
+
properties:
|
|
3108
|
+
items: { type: array, items: { $ref: "#/components/schemas/AccountAccess" } }
|
|
3109
|
+
required: [items]
|
|
3110
|
+
RequestableAccountPage:
|
|
3111
|
+
allOf:
|
|
3112
|
+
- $ref: "#/components/schemas/ListPage"
|
|
3113
|
+
- type: object
|
|
3114
|
+
properties:
|
|
3115
|
+
items: { type: array, items: { $ref: "#/components/schemas/RequestableAccount" } }
|
|
3116
|
+
required: [items]
|
|
3117
|
+
AdminAccountPage:
|
|
3118
|
+
allOf:
|
|
3119
|
+
- $ref: "#/components/schemas/ListPage"
|
|
3120
|
+
- type: object
|
|
3121
|
+
properties:
|
|
3122
|
+
items: { type: array, items: { $ref: "#/components/schemas/AdminAccount" } }
|
|
3123
|
+
required: [items]
|
|
3124
|
+
UserPage:
|
|
3125
|
+
allOf:
|
|
3126
|
+
- $ref: "#/components/schemas/ListPage"
|
|
3127
|
+
- type: object
|
|
3128
|
+
properties:
|
|
3129
|
+
items: { type: array, items: { $ref: "#/components/schemas/User" } }
|
|
3130
|
+
required: [items]
|
|
3131
|
+
PluginPermission:
|
|
3132
|
+
type: string
|
|
3133
|
+
enum: [user, admin]
|
|
3134
|
+
description: A plugin's two permission levels. `admin` includes `user` only where the plugin declares `user`.
|
|
3135
|
+
PluginPrincipal:
|
|
3136
|
+
type: object
|
|
3137
|
+
description: Who a plugin assignment is for. Groups are standing — they carry no expiry.
|
|
3138
|
+
oneOf:
|
|
3139
|
+
- type: object
|
|
3140
|
+
properties:
|
|
3141
|
+
kind: { type: string, enum: [user] }
|
|
3142
|
+
userId: { type: string, description: Cognito sub. }
|
|
3143
|
+
required: [kind, userId]
|
|
3144
|
+
- type: object
|
|
3145
|
+
properties:
|
|
3146
|
+
kind: { type: string, enum: [group] }
|
|
3147
|
+
groupId: { type: string }
|
|
3148
|
+
required: [kind, groupId]
|
|
3149
|
+
PluginUnavailableReason:
|
|
3150
|
+
type: string
|
|
3151
|
+
enum: [plugin-unknown, plugin-disabled, plugin-removed, plugin-unsupported, permission-undeclared, account-unbound, account-unregistered]
|
|
3152
|
+
description: Why a stored row cannot authorize anything right now.
|
|
3153
|
+
PluginAssignment:
|
|
3154
|
+
type: object
|
|
3155
|
+
description: One stored grant row, as the editor sees it. A row that is expired or unavailable is kept, shown, and revocable.
|
|
3156
|
+
properties:
|
|
3157
|
+
pluginId: { type: string }
|
|
3158
|
+
accountNumber: { type: string }
|
|
3159
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
3160
|
+
principal: { $ref: "#/components/schemas/PluginPrincipal" }
|
|
3161
|
+
grantedBy: { type: string }
|
|
3162
|
+
grantedAt: { type: string, format: date-time }
|
|
3163
|
+
expiresAt: { type: string, format: date-time }
|
|
3164
|
+
expired: { type: boolean }
|
|
3165
|
+
available: { type: boolean, description: Whether this row can authorize anything right now. }
|
|
3166
|
+
reason: { $ref: "#/components/schemas/PluginUnavailableReason" }
|
|
3167
|
+
required: [pluginId, accountNumber, permission, principal, expired, available]
|
|
3168
|
+
PluginCapability:
|
|
3169
|
+
type: object
|
|
3170
|
+
description: An effective capability, with the stored grants behind it. Implication is applied here, never stored.
|
|
3171
|
+
properties:
|
|
3172
|
+
pluginId: { type: string }
|
|
3173
|
+
accountNumber: { type: string }
|
|
3174
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
3175
|
+
available: { type: boolean }
|
|
3176
|
+
reason: { $ref: "#/components/schemas/PluginUnavailableReason" }
|
|
3177
|
+
sources:
|
|
3178
|
+
type: array
|
|
3179
|
+
description: The grants this capability cites — a user capability may cite an admin grant, never the reverse.
|
|
3180
|
+
items:
|
|
3181
|
+
type: object
|
|
3182
|
+
properties:
|
|
3183
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
3184
|
+
groups: { type: array, items: { type: string } }
|
|
3185
|
+
required: [permission, groups]
|
|
3186
|
+
required: [pluginId, accountNumber, permission, available, sources]
|
|
3187
|
+
PluginHolder:
|
|
3188
|
+
type: object
|
|
3189
|
+
description: Someone who can use the binding right now, directly or through a group.
|
|
3190
|
+
properties:
|
|
3191
|
+
userId: { type: string }
|
|
3192
|
+
email: { type: string }
|
|
3193
|
+
capabilities:
|
|
3194
|
+
type: array
|
|
3195
|
+
items: { $ref: "#/components/schemas/PluginCapability" }
|
|
3196
|
+
required: [userId, capabilities]
|
|
3197
|
+
UserPluginAccess:
|
|
3198
|
+
type: object
|
|
3199
|
+
description: A user's stored plugin rows and the capabilities they add up to (direct plus via groups).
|
|
3200
|
+
properties:
|
|
3201
|
+
assignments:
|
|
3202
|
+
type: array
|
|
3203
|
+
items: { $ref: "#/components/schemas/PluginAssignment" }
|
|
3204
|
+
capabilities:
|
|
3205
|
+
type: array
|
|
3206
|
+
items: { $ref: "#/components/schemas/PluginCapability" }
|
|
3207
|
+
required: [assignments, capabilities]
|
|
3208
|
+
PluginDiscoveryUiEntry:
|
|
3209
|
+
type: object
|
|
3210
|
+
properties:
|
|
3211
|
+
label: { type: string }
|
|
3212
|
+
icon: { type: string }
|
|
3213
|
+
order: { type: integer }
|
|
3214
|
+
url: { type: string, description: Absolute path on the portal origin, under the plugin's immutable asset prefix. }
|
|
3215
|
+
required: [label, url]
|
|
3216
|
+
PluginDiscovery:
|
|
3217
|
+
type: object
|
|
3218
|
+
description: Caller discovery. An empty list means the feature is off or nothing is registered.
|
|
3219
|
+
properties:
|
|
3220
|
+
schemaVersion: { type: integer, enum: [1] }
|
|
3221
|
+
refreshAfterSeconds: { type: integer, description: How long the portal may keep this before refreshing (15–300). }
|
|
3222
|
+
plugins:
|
|
3223
|
+
type: array
|
|
3224
|
+
items:
|
|
3225
|
+
type: object
|
|
3226
|
+
properties:
|
|
3227
|
+
id: { type: string }
|
|
3228
|
+
displayName: { type: string }
|
|
3229
|
+
description: { type: string }
|
|
3230
|
+
version: { type: string }
|
|
3231
|
+
revision: { type: string }
|
|
3232
|
+
apiBaseUrl: { type: string }
|
|
3233
|
+
ui:
|
|
3234
|
+
type: object
|
|
3235
|
+
properties:
|
|
3236
|
+
user: { $ref: "#/components/schemas/PluginDiscoveryUiEntry" }
|
|
3237
|
+
admin: { $ref: "#/components/schemas/PluginDiscoveryUiEntry" }
|
|
3238
|
+
accounts:
|
|
3239
|
+
type: array
|
|
3240
|
+
items:
|
|
3241
|
+
type: object
|
|
3242
|
+
properties:
|
|
3243
|
+
accountNumber: { type: string }
|
|
3244
|
+
displayName: { type: string, description: From the Accounts catalog, not from any IAM role grant. }
|
|
3245
|
+
regions: { type: array, items: { type: string } }
|
|
3246
|
+
permissions:
|
|
3247
|
+
type: array
|
|
3248
|
+
description: Effective capabilities on this account, not stored assignments.
|
|
3249
|
+
items: { $ref: "#/components/schemas/PluginPermission" }
|
|
3250
|
+
required: [accountNumber, displayName, permissions]
|
|
3251
|
+
required: [id, displayName, version, revision, apiBaseUrl, ui, accounts]
|
|
3252
|
+
required: [schemaVersion, refreshAfterSeconds, plugins]
|
|
3253
|
+
PluginAdminCatalog:
|
|
3254
|
+
type: object
|
|
3255
|
+
description: Every definition, for the grant editor.
|
|
3256
|
+
properties:
|
|
3257
|
+
schemaVersion: { type: integer, enum: [1] }
|
|
3258
|
+
plugins:
|
|
3259
|
+
type: array
|
|
3260
|
+
items:
|
|
3261
|
+
type: object
|
|
3262
|
+
properties:
|
|
3263
|
+
id: { type: string }
|
|
3264
|
+
displayName: { type: string }
|
|
3265
|
+
description: { type: string }
|
|
3266
|
+
version: { type: string }
|
|
3267
|
+
revision: { type: string }
|
|
3268
|
+
schemaVersion: { type: integer }
|
|
3269
|
+
hostApiVersion: { type: integer }
|
|
3270
|
+
status: { type: string, enum: [active, disabled, removed, unsupported] }
|
|
3271
|
+
enabled: { type: boolean }
|
|
3272
|
+
installed: { type: boolean, description: false = tombstone, kept so historical grants keep their labels. }
|
|
3273
|
+
permissions:
|
|
3274
|
+
type: array
|
|
3275
|
+
items:
|
|
3276
|
+
type: object
|
|
3277
|
+
properties:
|
|
3278
|
+
id: { $ref: "#/components/schemas/PluginPermission" }
|
|
3279
|
+
label: { type: string }
|
|
3280
|
+
description: { type: string }
|
|
3281
|
+
implies:
|
|
3282
|
+
type: array
|
|
3283
|
+
items: { $ref: "#/components/schemas/PluginPermission" }
|
|
3284
|
+
required: [id, label, implies]
|
|
3285
|
+
accounts:
|
|
3286
|
+
type: array
|
|
3287
|
+
items:
|
|
3288
|
+
type: object
|
|
3289
|
+
properties:
|
|
3290
|
+
accountNumber: { type: string }
|
|
3291
|
+
displayName: { type: string }
|
|
3292
|
+
regions: { type: array, items: { type: string } }
|
|
3293
|
+
available: { type: boolean }
|
|
3294
|
+
reason: { type: string, enum: [unregistered] }
|
|
3295
|
+
required: [accountNumber, available]
|
|
3296
|
+
ui:
|
|
3297
|
+
type: object
|
|
3298
|
+
properties:
|
|
3299
|
+
user: { type: object, properties: { label: { type: string }, icon: { type: string }, order: { type: integer } }, required: [label] }
|
|
3300
|
+
admin: { type: object, properties: { label: { type: string }, icon: { type: string }, order: { type: integer } }, required: [label] }
|
|
3301
|
+
routes:
|
|
3302
|
+
type: array
|
|
3303
|
+
items:
|
|
3304
|
+
type: object
|
|
3305
|
+
properties:
|
|
3306
|
+
id: { type: string }
|
|
3307
|
+
method: { type: string }
|
|
3308
|
+
path: { type: string }
|
|
3309
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
3310
|
+
required: [id, method, path, permission]
|
|
3311
|
+
updatedAt: { type: string, format: date-time }
|
|
3312
|
+
required: [id, displayName, version, revision, schemaVersion, hostApiVersion, status, enabled, installed, permissions, accounts, ui, routes, updatedAt]
|
|
3313
|
+
required: [schemaVersion, plugins]
|
|
3314
|
+
Error:
|
|
3315
|
+
type: object
|
|
3316
|
+
properties:
|
|
3317
|
+
message: { type: string }
|
|
3318
|
+
required: [message]
|
|
3319
|
+
Message:
|
|
3320
|
+
type: object
|
|
3321
|
+
properties:
|
|
3322
|
+
message: { type: string }
|
|
3323
|
+
required: [message]
|
|
3324
|
+
Cleared:
|
|
3325
|
+
type: object
|
|
3326
|
+
properties:
|
|
3327
|
+
cleared: { type: integer, description: How many rows were newly marked seen. }
|
|
3328
|
+
required: [cleared]
|
|
3329
|
+
AccountNumber:
|
|
3330
|
+
type: string
|
|
3331
|
+
pattern: "^\\d{12}$"
|
|
3332
|
+
description: 12-digit AWS account id.
|
|
3333
|
+
example: "123456789012"
|
|
3334
|
+
DurationHours:
|
|
3335
|
+
type: integer
|
|
3336
|
+
enum: [1, 12, 24, 72, 168, 720]
|
|
3337
|
+
description: Temporary-access preset in hours (1 h, 12 h, 1 d, 3 d, 7 d, 30 d). Omit for long-term access.
|
|
3338
|
+
RoleRef:
|
|
3339
|
+
type: object
|
|
3340
|
+
properties:
|
|
3341
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3342
|
+
roleName: { type: string }
|
|
3343
|
+
required: [accountNumber, roleName]
|
|
3344
|
+
UserIdList:
|
|
3345
|
+
type: object
|
|
3346
|
+
properties:
|
|
3347
|
+
userIds: { type: array, items: { type: string }, minItems: 1 }
|
|
3348
|
+
required: [userIds]
|
|
3349
|
+
ProfileNameValue:
|
|
3350
|
+
type: object
|
|
3351
|
+
properties:
|
|
3352
|
+
profileName: { type: [string, "null"] }
|
|
3353
|
+
required: [profileName]
|
|
3354
|
+
|
|
3355
|
+
Discovery:
|
|
3356
|
+
type: object
|
|
3357
|
+
properties:
|
|
3358
|
+
projectName: { type: string, description: "Empty when unset — clients fall back to the hostname." }
|
|
3359
|
+
cognito:
|
|
3360
|
+
type: object
|
|
3361
|
+
properties:
|
|
3362
|
+
userPoolId: { type: string }
|
|
3363
|
+
clientId: { type: string }
|
|
3364
|
+
region: { type: string }
|
|
3365
|
+
required: [userPoolId, clientId, region]
|
|
3366
|
+
issuer: { type: string, format: uri, description: The OIDC issuer URL baked into cross-account trust. }
|
|
3367
|
+
network:
|
|
3368
|
+
type: [object, "null"]
|
|
3369
|
+
description: "`null` when no private network is deployed."
|
|
3370
|
+
properties:
|
|
3371
|
+
controlUrl: { type: string, format: uri, description: Legacy single-site field (first site). }
|
|
3372
|
+
sites:
|
|
3373
|
+
type: array
|
|
3374
|
+
items:
|
|
3375
|
+
type: object
|
|
3376
|
+
properties:
|
|
3377
|
+
id: { type: string }
|
|
3378
|
+
displayName: { type: string }
|
|
3379
|
+
controlUrl: { type: string, format: uri }
|
|
3380
|
+
required: [id, displayName, controlUrl]
|
|
3381
|
+
required: [controlUrl, sites]
|
|
3382
|
+
required: [projectName, cognito, issuer, network]
|
|
3383
|
+
|
|
3384
|
+
AccountAccess:
|
|
3385
|
+
type: object
|
|
3386
|
+
properties:
|
|
3387
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3388
|
+
name: { type: string, description: Admin-set friendly name. }
|
|
3389
|
+
environment: { type: string }
|
|
3390
|
+
dims: { $ref: "#/components/schemas/AccountDims" }
|
|
3391
|
+
sortOrder: { type: integer, minimum: 0, description: Admin-set display position; the list is already in this order. }
|
|
3392
|
+
position: { type: integer, minimum: 0, description: Index in the admin order (the `position` sort key). }
|
|
3393
|
+
main: { type: boolean, enum: [false], description: Present (false) only for an account an admin took off the dashboard's Main section. }
|
|
3394
|
+
roles:
|
|
3395
|
+
type: array
|
|
3396
|
+
items: { $ref: "#/components/schemas/RoleAccess" }
|
|
3397
|
+
required: [accountNumber, position, roles]
|
|
3398
|
+
RoleAccess:
|
|
3399
|
+
type: object
|
|
3400
|
+
properties:
|
|
3401
|
+
role: { type: string }
|
|
3402
|
+
roleArn: { type: string }
|
|
3403
|
+
displayName: { type: string }
|
|
3404
|
+
description: { type: string }
|
|
3405
|
+
icon: { type: string }
|
|
3406
|
+
expiresAt: { type: string, format: date-time, description: End of a temporary grant; absent = long-term. }
|
|
3407
|
+
profileName: { type: string, description: THE `~/.aws` profile name for this role — what the desktop writes. }
|
|
3408
|
+
profileSource: { type: string, enum: [override, account, role, default] }
|
|
3409
|
+
suggestedProfileName: { type: string, description: What the name would be without the caller's override. }
|
|
3410
|
+
required: [role, roleArn, profileName, profileSource, suggestedProfileName]
|
|
3411
|
+
VendedCredentials:
|
|
3412
|
+
type: object
|
|
3413
|
+
properties:
|
|
3414
|
+
accessKeyId: { type: string }
|
|
3415
|
+
secretKey: { type: string }
|
|
3416
|
+
sessionToken: { type: string }
|
|
3417
|
+
expiration: { type: string, format: date-time }
|
|
3418
|
+
required: [accessKeyId, secretKey, sessionToken]
|
|
3419
|
+
ConsoleSignIn:
|
|
3420
|
+
type: object
|
|
3421
|
+
properties:
|
|
3422
|
+
url: { type: string, format: uri, description: Short-lived federation sign-in URL. }
|
|
3423
|
+
expiration: { type: string, format: date-time }
|
|
3424
|
+
required: [url]
|
|
3425
|
+
ExpiryNotice:
|
|
3426
|
+
type: object
|
|
3427
|
+
properties:
|
|
3428
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3429
|
+
roleName: { type: string }
|
|
3430
|
+
expiresAt: { type: string, format: date-time }
|
|
3431
|
+
seen: { type: boolean, description: Acknowledged for THIS phase (expiring vs expired). }
|
|
3432
|
+
required: [accountNumber, roleName, expiresAt, seen]
|
|
3433
|
+
ExpiryNotices:
|
|
3434
|
+
type: object
|
|
3435
|
+
properties:
|
|
3436
|
+
expiring: { type: array, items: { $ref: "#/components/schemas/ExpiryNotice" } }
|
|
3437
|
+
expired: { type: array, items: { $ref: "#/components/schemas/ExpiryNotice" } }
|
|
3438
|
+
required: [expiring, expired]
|
|
3439
|
+
|
|
3440
|
+
RequestableAccount:
|
|
3441
|
+
type: object
|
|
3442
|
+
properties:
|
|
3443
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3444
|
+
name: { type: string }
|
|
3445
|
+
dims: { $ref: "#/components/schemas/AccountDims" }
|
|
3446
|
+
roles:
|
|
3447
|
+
type: array
|
|
3448
|
+
items:
|
|
3449
|
+
type: object
|
|
3450
|
+
properties:
|
|
3451
|
+
roleName: { type: string }
|
|
3452
|
+
displayName: { type: string }
|
|
3453
|
+
description: { type: string }
|
|
3454
|
+
required: [roleName]
|
|
3455
|
+
required: [accountNumber, roles]
|
|
3456
|
+
RequestableResource:
|
|
3457
|
+
type: object
|
|
3458
|
+
properties:
|
|
3459
|
+
resourceId: { type: string }
|
|
3460
|
+
name: { type: string }
|
|
3461
|
+
type: { $ref: "#/components/schemas/ResourceType" }
|
|
3462
|
+
description: { type: string }
|
|
3463
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3464
|
+
accountName: { type: string }
|
|
3465
|
+
required: [resourceId, name, type, accountNumber]
|
|
3466
|
+
AccessRequest:
|
|
3467
|
+
type: object
|
|
3468
|
+
description: One access request or review. `kind` says what is under decision; `type` whether it was raised by a user (`ACCESS`) or by the periodic review sweep (`REAPPROVAL`).
|
|
3469
|
+
properties:
|
|
3470
|
+
requestId: { type: string }
|
|
3471
|
+
userId: { type: string, description: "The requester's sub (reapproval: the holder; group reapproval: the groupId; service-user review: the client id)." }
|
|
3472
|
+
kind: { type: string, enum: [ROLE, RESOURCE, ADMIN, SERVICE_USER, PLUGIN, GROUP], description: "PLUGIN = a plugin permission (pluginId + accountNumber + permission); GROUP = the yearly review of a whole group's bundle (userId and groupId are the group; approve restarts its clock, deny deletes the group). Both reapproval-only." }
|
|
3473
|
+
type: { type: string, enum: [ACCESS, REAPPROVAL] }
|
|
3474
|
+
groupId: { type: string, description: Set on group reapprovals. }
|
|
3475
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3476
|
+
roleName: { type: string }
|
|
3477
|
+
resourceId: { type: string }
|
|
3478
|
+
pluginId: { type: string, description: Set on PLUGIN rows. }
|
|
3479
|
+
permission: { type: string, enum: [user, admin], description: Set on PLUGIN rows. }
|
|
3480
|
+
resourceName: { type: string, description: Resolved by the route on RESOURCE rows. }
|
|
3481
|
+
reason: { type: string }
|
|
3482
|
+
requestedDurationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
3483
|
+
grantedDurationHours: { $ref: "#/components/schemas/DurationHours" }
|
|
3484
|
+
status: { type: string, enum: [PENDING, APPROVED, DENIED] }
|
|
3485
|
+
createdAt: { type: string, format: date-time }
|
|
3486
|
+
decidedAt: { type: string, format: date-time }
|
|
3487
|
+
decidedBy: { type: string }
|
|
3488
|
+
decisionNote: { type: string }
|
|
3489
|
+
seen: { type: boolean, description: Requester acknowledged the decision. }
|
|
3490
|
+
required: [requestId, userId, status, createdAt]
|
|
3491
|
+
AccessRequestAdminView:
|
|
3492
|
+
allOf:
|
|
3493
|
+
- $ref: "#/components/schemas/AccessRequest"
|
|
3494
|
+
- type: object
|
|
3495
|
+
properties:
|
|
3496
|
+
email: { type: string, description: Requester's email; empty if the user is gone. }
|
|
3497
|
+
serviceUser: { type: string, description: Registry name when the requester is a service user. }
|
|
3498
|
+
group: { type: string, description: Group name on group reapprovals. }
|
|
3499
|
+
usage:
|
|
3500
|
+
type: object
|
|
3501
|
+
description: Only with `?usage=1` on pending role reapprovals.
|
|
3502
|
+
properties:
|
|
3503
|
+
count: { type: integer }
|
|
3504
|
+
lastAt: { type: string, format: date-time }
|
|
3505
|
+
required: [count]
|
|
3506
|
+
required: [email]
|
|
3507
|
+
RequestEnvelope:
|
|
3508
|
+
type: object
|
|
3509
|
+
properties:
|
|
3510
|
+
request: { $ref: "#/components/schemas/AccessRequest" }
|
|
3511
|
+
required: [request]
|
|
3512
|
+
|
|
3513
|
+
RolePreference:
|
|
3514
|
+
type: object
|
|
3515
|
+
properties:
|
|
3516
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3517
|
+
role: { type: string }
|
|
3518
|
+
profileName: { type: [string, "null"] }
|
|
3519
|
+
roleLabel: { type: [string, "null"] }
|
|
3520
|
+
autoVend: { type: boolean }
|
|
3521
|
+
required: [accountNumber, role, profileName, roleLabel, autoVend]
|
|
3522
|
+
NetworkPrefs:
|
|
3523
|
+
type: object
|
|
3524
|
+
properties:
|
|
3525
|
+
autoReconnect: { type: boolean }
|
|
3526
|
+
lastSiteId: { type: [string, "null"] }
|
|
3527
|
+
required: [autoReconnect, lastSiteId]
|
|
3528
|
+
|
|
3529
|
+
NotificationPrefs:
|
|
3530
|
+
type: object
|
|
3531
|
+
properties:
|
|
3532
|
+
enabled: { type: boolean, description: Master switch. }
|
|
3533
|
+
kinds:
|
|
3534
|
+
type: object
|
|
3535
|
+
description: Per item kind — granted (a direct grant), revoked, decided (a request decision), expiring (temporary access near or past its end), session (the sign-in is about to reach its cap), requests (admins — a new request waiting), reviews (admins — yearly reviews raised).
|
|
3536
|
+
additionalProperties: { type: boolean }
|
|
3537
|
+
required: [enabled, kinds]
|
|
3538
|
+
|
|
3539
|
+
PublicSite:
|
|
3540
|
+
type: object
|
|
3541
|
+
properties:
|
|
3542
|
+
id: { type: string }
|
|
3543
|
+
displayName: { type: string }
|
|
3544
|
+
controlUrl: { type: string, format: uri }
|
|
3545
|
+
accounts: { type: array, items: { $ref: "#/components/schemas/AccountNumber" }, description: Accounts in this routing domain. }
|
|
3546
|
+
required: [id, controlUrl, accounts]
|
|
3547
|
+
NetworkSite:
|
|
3548
|
+
allOf:
|
|
3549
|
+
- $ref: "#/components/schemas/PublicSite"
|
|
3550
|
+
- type: object
|
|
3551
|
+
properties:
|
|
3552
|
+
splitDns:
|
|
3553
|
+
type: object
|
|
3554
|
+
additionalProperties: { type: array, items: { type: string } }
|
|
3555
|
+
description: Private zone → resolver IPs.
|
|
3556
|
+
connectorVpcs:
|
|
3557
|
+
type: object
|
|
3558
|
+
additionalProperties:
|
|
3559
|
+
type: array
|
|
3560
|
+
items:
|
|
3561
|
+
type: object
|
|
3562
|
+
properties:
|
|
3563
|
+
vpcId: { type: string }
|
|
3564
|
+
routes: { type: array, items: { type: string } }
|
|
3565
|
+
region: { type: string, description: Set when the VPC is outside the hub's region. }
|
|
3566
|
+
name: { type: string, description: Set for every connector VPC of an account but its one unnamed VPC; suffixes the connector hostname. }
|
|
3567
|
+
required: [vpcId, routes]
|
|
3568
|
+
description: Keyed by account number, one entry per connector VPC.
|
|
3569
|
+
DevShareGrantee:
|
|
3570
|
+
type: object
|
|
3571
|
+
properties:
|
|
3572
|
+
kind: { type: string, enum: [user, group] }
|
|
3573
|
+
id: { type: string }
|
|
3574
|
+
name: { type: string, description: Email (user) or group name; the id when the directory no longer knows it. }
|
|
3575
|
+
required: [kind, id, name]
|
|
3576
|
+
DevShare:
|
|
3577
|
+
type: object
|
|
3578
|
+
description: A dev share as its owner (or an admin) sees it.
|
|
3579
|
+
properties:
|
|
3580
|
+
shareId: { type: string, pattern: "^[a-f0-9]{12}$" }
|
|
3581
|
+
ownerSub: { type: string }
|
|
3582
|
+
ownerName: { type: string, description: The owner's email at creation. }
|
|
3583
|
+
port: { type: integer }
|
|
3584
|
+
label: { type: string }
|
|
3585
|
+
siteId: { type: string }
|
|
3586
|
+
hostname: { type: string }
|
|
3587
|
+
ip: { type: string }
|
|
3588
|
+
url:
|
|
3589
|
+
type: [string, "null"]
|
|
3590
|
+
description: "`http://<hostname|ip>:<port>`; null until the desktop app reported an address."
|
|
3591
|
+
createdAt: { type: string, format: date-time }
|
|
3592
|
+
expiresAt: { type: string, format: date-time }
|
|
3593
|
+
grantees: { type: array, items: { $ref: "#/components/schemas/DevShareGrantee" } }
|
|
3594
|
+
required: [shareId, ownerSub, ownerName, port, label, siteId, url, createdAt, expiresAt, grantees]
|
|
3595
|
+
DevShareWithMe:
|
|
3596
|
+
type: object
|
|
3597
|
+
description: A dev share as a grantee sees it (no grantee list).
|
|
3598
|
+
properties:
|
|
3599
|
+
shareId: { type: string }
|
|
3600
|
+
ownerSub: { type: string }
|
|
3601
|
+
ownerName: { type: string }
|
|
3602
|
+
port: { type: integer }
|
|
3603
|
+
label: { type: string }
|
|
3604
|
+
siteId: { type: string }
|
|
3605
|
+
url: { type: [string, "null"] }
|
|
3606
|
+
expiresAt: { type: string, format: date-time }
|
|
3607
|
+
viaGroups:
|
|
3608
|
+
type: array
|
|
3609
|
+
items: { type: string }
|
|
3610
|
+
description: Names of the caller's groups the share came through; empty = granted directly.
|
|
3611
|
+
required: [shareId, ownerSub, ownerName, port, label, siteId, url, expiresAt, viaGroups]
|
|
3612
|
+
DevShareDirectory:
|
|
3613
|
+
type: object
|
|
3614
|
+
properties:
|
|
3615
|
+
users:
|
|
3616
|
+
type: array
|
|
3617
|
+
items:
|
|
3618
|
+
type: object
|
|
3619
|
+
properties:
|
|
3620
|
+
userId: { type: string }
|
|
3621
|
+
email: { type: string }
|
|
3622
|
+
required: [userId, email]
|
|
3623
|
+
groups:
|
|
3624
|
+
type: array
|
|
3625
|
+
items:
|
|
3626
|
+
type: object
|
|
3627
|
+
properties:
|
|
3628
|
+
groupId: { type: string }
|
|
3629
|
+
name: { type: string }
|
|
3630
|
+
members: { type: integer }
|
|
3631
|
+
required: [groupId, name, members]
|
|
3632
|
+
required: [users, groups]
|
|
3633
|
+
|
|
3634
|
+
DeviceKey:
|
|
3635
|
+
type: object
|
|
3636
|
+
properties:
|
|
3637
|
+
key: { type: string, description: Single-use enrollment key. }
|
|
3638
|
+
expiresAt: { type: string, format: date-time }
|
|
3639
|
+
controlUrl: { type: string, format: uri }
|
|
3640
|
+
siteId: { type: string }
|
|
3641
|
+
required: [key, expiresAt, controlUrl, siteId]
|
|
3642
|
+
|
|
3643
|
+
ResourceType:
|
|
3644
|
+
type: string
|
|
3645
|
+
enum: [DATABASE, WEB, HOST]
|
|
3646
|
+
ReachableResource:
|
|
3647
|
+
type: object
|
|
3648
|
+
properties:
|
|
3649
|
+
resourceId: { type: string }
|
|
3650
|
+
name: { type: string }
|
|
3651
|
+
type: { $ref: "#/components/schemas/ResourceType" }
|
|
3652
|
+
cidr: { type: string }
|
|
3653
|
+
ports: { type: array, items: { type: integer } }
|
|
3654
|
+
dnsName: { type: string }
|
|
3655
|
+
sshUser: { type: string }
|
|
3656
|
+
description: { type: string }
|
|
3657
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3658
|
+
accountName: { type: string }
|
|
3659
|
+
expiresAt: { type: string, format: date-time, description: Absent = long-term. }
|
|
3660
|
+
required: [resourceId, name, type, cidr, ports, accountNumber]
|
|
3661
|
+
PluginExpiryNotice:
|
|
3662
|
+
type: object
|
|
3663
|
+
properties:
|
|
3664
|
+
pluginId: { type: string }
|
|
3665
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3666
|
+
permission: { $ref: "#/components/schemas/PluginPermission" }
|
|
3667
|
+
expiresAt: { type: string, format: date-time }
|
|
3668
|
+
seen: { type: boolean }
|
|
3669
|
+
pluginName: { type: string }
|
|
3670
|
+
accountName: { type: string }
|
|
3671
|
+
required: [pluginId, accountNumber, permission, expiresAt, seen, pluginName, accountName]
|
|
3672
|
+
ResourceExpiryNotice:
|
|
3673
|
+
type: object
|
|
3674
|
+
properties:
|
|
3675
|
+
resourceId: { type: string }
|
|
3676
|
+
name: { type: string }
|
|
3677
|
+
expiresAt: { type: string, format: date-time }
|
|
3678
|
+
seen: { type: boolean }
|
|
3679
|
+
required: [resourceId, name, expiresAt, seen]
|
|
3680
|
+
RevocationNotice:
|
|
3681
|
+
type: object
|
|
3682
|
+
description: One access change for the bell — a loss, or (since the activity log) a gain the person did not ask for. `revokedAt` is the notice's timestamp either way.
|
|
3683
|
+
properties:
|
|
3684
|
+
noticeId: { type: string }
|
|
3685
|
+
change: { type: string, enum: [GRANTED, REVOKED], description: Rows written before grants were noticed are REVOKED. }
|
|
3686
|
+
kind: { type: string, enum: [ROLE, RESOURCE, SHARE, PLUGIN, BUNDLE], description: SHARE = a dev share stopped early (resourceId = share id, resourceName = its label). PLUGIN = a plugin permission lost (pluginId + accountNumber + permission, pluginName = the plugin's display name). BUNDLE = one row for `count` targets that changed together (more than five gained or lost by one person through a group membership or bundle edit, or a cascade); groupId/groupName when a group carried it. Direct admin grants and revokes stay one row per target. }
|
|
3687
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3688
|
+
roleName: { type: string }
|
|
3689
|
+
resourceId: { type: string }
|
|
3690
|
+
resourceName: { type: string }
|
|
3691
|
+
pluginId: { type: string }
|
|
3692
|
+
permission: { type: string, enum: [user, admin] }
|
|
3693
|
+
pluginName: { type: string }
|
|
3694
|
+
count: { type: integer, description: BUNDLE only — how many targets the row stands for. }
|
|
3695
|
+
groupId: { type: string, description: BUNDLE only — the group whose membership or bundle edit carried the change. }
|
|
3696
|
+
groupName: { type: string, description: BUNDLE only — that group's name at the time. }
|
|
3697
|
+
revokedAt: { type: string, format: date-time }
|
|
3698
|
+
via: { type: string, enum: [ADMIN, GROUP, REAPPROVAL, CASCADE, OWNER] }
|
|
3699
|
+
seen: { type: boolean }
|
|
3700
|
+
required: [noticeId, change, kind, revokedAt, via, seen]
|
|
3701
|
+
|
|
3702
|
+
SetupStatus:
|
|
3703
|
+
type: object
|
|
3704
|
+
properties:
|
|
3705
|
+
issuerUrl: { type: string, format: uri }
|
|
3706
|
+
region: { type: string }
|
|
3707
|
+
emailConfigured: { type: boolean }
|
|
3708
|
+
emailFrom: { type: string }
|
|
3709
|
+
accounts: { type: integer }
|
|
3710
|
+
roles: { type: integer }
|
|
3711
|
+
usersTotal: { type: integer }
|
|
3712
|
+
invitedActive: { type: boolean, description: Someone other than the caller has finished sign-in. }
|
|
3713
|
+
vended: { type: boolean, description: At least one successful vend or console-open is on record. }
|
|
3714
|
+
configAccounts:
|
|
3715
|
+
type: array
|
|
3716
|
+
items:
|
|
3717
|
+
type: object
|
|
3718
|
+
properties:
|
|
3719
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3720
|
+
roles: { type: array, items: { type: string } }
|
|
3721
|
+
registered: { type: boolean }
|
|
3722
|
+
required: [accountNumber, roles, registered]
|
|
3723
|
+
required: [issuerUrl, region, emailConfigured, accounts, roles, usersTotal, invitedActive, vended, configAccounts]
|
|
3724
|
+
BrandingOverlay:
|
|
3725
|
+
type: object
|
|
3726
|
+
properties:
|
|
3727
|
+
projectName: { type: string }
|
|
3728
|
+
logoUrl: { type: string, description: "`https://` URL or `data:image/*` URI (≤ 64 KB)." }
|
|
3729
|
+
primaryColor: { type: string, pattern: "^#([0-9a-fA-F]{3}|[0-9a-fA-F]{6})$" }
|
|
3730
|
+
primaryHoverColor: { type: string }
|
|
3731
|
+
accentColor: { type: string }
|
|
3732
|
+
grayTone: { type: string }
|
|
3733
|
+
radius: { type: string }
|
|
3734
|
+
iconSet: { type: string, enum: [outline, bold, solid] }
|
|
3735
|
+
panelStrength: { type: integer, minimum: 0, maximum: 100 }
|
|
3736
|
+
accentDepth: { type: integer, minimum: 0, maximum: 100 }
|
|
3737
|
+
borderStrength: { type: integer, minimum: 0, maximum: 100 }
|
|
3738
|
+
gradientStrength: { type: integer, minimum: 0, maximum: 100 }
|
|
3739
|
+
|
|
3740
|
+
AdminAccount:
|
|
3741
|
+
type: object
|
|
3742
|
+
properties:
|
|
3743
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3744
|
+
name: { type: string }
|
|
3745
|
+
environment: { type: string }
|
|
3746
|
+
status: { type: string }
|
|
3747
|
+
profileName: { type: string }
|
|
3748
|
+
sortOrder: { type: integer, minimum: 0, description: "Display position (PUT /admin/accounts/order); absent = after the ordered ones. The list is already in this order." }
|
|
3749
|
+
main: { type: boolean, description: "Shown in everyone's dashboard Main section (the default). Sections appear on a user's dashboard only once they hold an account that is not main." }
|
|
3750
|
+
dims: { $ref: "#/components/schemas/AccountDims" }
|
|
3751
|
+
position: { type: integer, minimum: 0, description: Index in the admin order (the `position` sort key). }
|
|
3752
|
+
roles: { type: array, items: { $ref: "#/components/schemas/AdminRole" } }
|
|
3753
|
+
required: [accountNumber, roles]
|
|
3754
|
+
DashboardLayout:
|
|
3755
|
+
type: object
|
|
3756
|
+
properties:
|
|
3757
|
+
mode: { type: string, enum: [auto, sections, plain] }
|
|
3758
|
+
required: [mode]
|
|
3759
|
+
AccountDims:
|
|
3760
|
+
type: object
|
|
3761
|
+
description: |
|
|
3762
|
+
Account dimensions (deployments with `accountDimensions` on): read off the name at registration — first hyphen-separated
|
|
3763
|
+
segment = tenant, last = stage, the rest = project (`acme-data-platform-prod`; `acme-prod` has no project) — editable by an
|
|
3764
|
+
admin afterwards and never re-derived when the account is renamed. They filter lists; they never decide access.
|
|
3765
|
+
properties:
|
|
3766
|
+
tenant: { type: string, minLength: 1 }
|
|
3767
|
+
project: { type: string, minLength: 1 }
|
|
3768
|
+
stage: { type: string, minLength: 1 }
|
|
3769
|
+
required: [tenant, stage]
|
|
3770
|
+
AdminRole:
|
|
3771
|
+
type: object
|
|
3772
|
+
properties:
|
|
3773
|
+
roleName: { type: string }
|
|
3774
|
+
displayName: { type: string }
|
|
3775
|
+
roleArn: { type: string }
|
|
3776
|
+
policyTier: { type: string }
|
|
3777
|
+
description: { type: string }
|
|
3778
|
+
color: { type: string, description: "Chip tint `#rrggbb`." }
|
|
3779
|
+
icon: { type: string, enum: [view, admin, operate, deploy, data, billing, analytics, access] }
|
|
3780
|
+
profileName: { type: string }
|
|
3781
|
+
sessionDurationSeconds: { type: integer, minimum: 900, maximum: 43200 }
|
|
3782
|
+
sortOrder: { type: integer, minimum: 0, description: "Display position inside the account (PUT /admin/accounts/order); absent = after the ordered ones. Lists are already in this order." }
|
|
3783
|
+
grantees: { type: integer, description: Unexpired holders (list route only). }
|
|
3784
|
+
required: [roleName, roleArn]
|
|
3785
|
+
AccountEnvelope:
|
|
3786
|
+
type: object
|
|
3787
|
+
properties:
|
|
3788
|
+
account: { $ref: "#/components/schemas/AdminAccount" }
|
|
3789
|
+
required: [account]
|
|
3790
|
+
RoleEnvelope:
|
|
3791
|
+
type: object
|
|
3792
|
+
properties:
|
|
3793
|
+
role: { $ref: "#/components/schemas/AdminRole" }
|
|
3794
|
+
required: [role]
|
|
3795
|
+
ProfileName:
|
|
3796
|
+
type: string
|
|
3797
|
+
pattern: "^([A-Za-z0-9][A-Za-z0-9_.-]{0,63})?$"
|
|
3798
|
+
description: A `~/.aws/credentials` section name (letters, digits, `.`, `_`, `-`); empty string clears.
|
|
3799
|
+
AccountCreate:
|
|
3800
|
+
type: object
|
|
3801
|
+
properties:
|
|
3802
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3803
|
+
name: { type: string }
|
|
3804
|
+
environment: { type: string }
|
|
3805
|
+
status: { type: string }
|
|
3806
|
+
profileName: { $ref: "#/components/schemas/ProfileName" }
|
|
3807
|
+
main: { type: boolean, default: true, description: "On everyone's dashboard Main section. A pipeline registering rarely used accounts passes false." }
|
|
3808
|
+
dims: { $ref: "#/components/schemas/AccountDims", description: "Explicit dimensions (a pipeline that knows them). Omitted, they are read off `name` when the deployment has account dimensions on." }
|
|
3809
|
+
required: [accountNumber]
|
|
3810
|
+
AccountOrder:
|
|
3811
|
+
type: object
|
|
3812
|
+
properties:
|
|
3813
|
+
accounts:
|
|
3814
|
+
type: array
|
|
3815
|
+
minItems: 1
|
|
3816
|
+
maxItems: 5000
|
|
3817
|
+
items:
|
|
3818
|
+
type: object
|
|
3819
|
+
properties:
|
|
3820
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3821
|
+
roles:
|
|
3822
|
+
type: array
|
|
3823
|
+
maxItems: 200
|
|
3824
|
+
uniqueItems: true
|
|
3825
|
+
items: { type: string, minLength: 1, maxLength: 64 }
|
|
3826
|
+
description: The account's roles, first to last; omit to leave their positions alone.
|
|
3827
|
+
required: [accountNumber]
|
|
3828
|
+
required: [accounts]
|
|
3829
|
+
AccountPatch:
|
|
3830
|
+
type: object
|
|
3831
|
+
description: At least one field.
|
|
3832
|
+
properties:
|
|
3833
|
+
name: { type: string }
|
|
3834
|
+
environment: { type: string }
|
|
3835
|
+
status: { type: string }
|
|
3836
|
+
profileName: { $ref: "#/components/schemas/ProfileName" }
|
|
3837
|
+
main: { type: boolean, description: "On everyone's dashboard Main section (true is the default state of an account)." }
|
|
3838
|
+
dims:
|
|
3839
|
+
oneOf:
|
|
3840
|
+
- $ref: "#/components/schemas/AccountDims"
|
|
3841
|
+
- type: "null"
|
|
3842
|
+
description: The admin's correction of tenant / project / stage; `null` clears them. A rename never changes them.
|
|
3843
|
+
RoleCreate:
|
|
3844
|
+
type: object
|
|
3845
|
+
properties:
|
|
3846
|
+
roleName: { type: string, description: "May not contain `#` or `/`." }
|
|
3847
|
+
displayName: { type: string, maxLength: 128 }
|
|
3848
|
+
roleArn: { type: string, pattern: "^arn:aws:iam::\\d{12}:role/.+" }
|
|
3849
|
+
policyTier: { type: string }
|
|
3850
|
+
description: { type: string }
|
|
3851
|
+
color: { type: string, pattern: "^(#[0-9a-fA-F]{6})?$" }
|
|
3852
|
+
icon: { type: string, enum: ["", view, admin, operate, deploy, data, billing, analytics, access] }
|
|
3853
|
+
profileName: { $ref: "#/components/schemas/ProfileName" }
|
|
3854
|
+
sessionDurationSeconds: { type: integer, minimum: 900, maximum: 43200 }
|
|
3855
|
+
required: [roleName, roleArn]
|
|
3856
|
+
RolePatch:
|
|
3857
|
+
type: object
|
|
3858
|
+
description: At least one field.
|
|
3859
|
+
properties:
|
|
3860
|
+
displayName: { type: string, maxLength: 128 }
|
|
3861
|
+
roleArn: { type: string, pattern: "^arn:aws:iam::\\d{12}:role/.+" }
|
|
3862
|
+
policyTier: { type: string }
|
|
3863
|
+
description: { type: string }
|
|
3864
|
+
color: { type: string, pattern: "^(#[0-9a-fA-F]{6})?$" }
|
|
3865
|
+
icon: { type: string, enum: ["", view, admin, operate, deploy, data, billing, analytics, access] }
|
|
3866
|
+
profileName: { $ref: "#/components/schemas/ProfileName" }
|
|
3867
|
+
sessionDurationSeconds: { type: integer, minimum: 900, maximum: 43200 }
|
|
3868
|
+
TestSessionResult:
|
|
3869
|
+
type: object
|
|
3870
|
+
properties:
|
|
3871
|
+
ok: { type: boolean }
|
|
3872
|
+
message: { type: string, description: STS's message when `ok` is false. }
|
|
3873
|
+
expiration: { type: string, format: date-time }
|
|
3874
|
+
required: [ok]
|
|
3875
|
+
|
|
3876
|
+
Grant:
|
|
3877
|
+
type: object
|
|
3878
|
+
properties:
|
|
3879
|
+
userId: { type: string }
|
|
3880
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3881
|
+
roleName: { type: string }
|
|
3882
|
+
expiresAt: { type: string, format: date-time, description: Absent = long-term. }
|
|
3883
|
+
required: [userId, accountNumber, roleName]
|
|
3884
|
+
Grantee:
|
|
3885
|
+
type: object
|
|
3886
|
+
properties:
|
|
3887
|
+
userId: { type: string }
|
|
3888
|
+
grantedBy: { type: string }
|
|
3889
|
+
grantedAt: { type: string, format: date-time }
|
|
3890
|
+
expiresAt: { type: string, format: date-time }
|
|
3891
|
+
direct: { type: boolean, description: Holds a direct grant row. }
|
|
3892
|
+
viaGroup: { type: string, description: First group providing it when there is no direct grant. }
|
|
3893
|
+
viaGroups: { type: array, items: { type: string }, description: Every group of theirs whose bundle holds it. }
|
|
3894
|
+
required: [userId, direct, viaGroups]
|
|
3895
|
+
UserGrant:
|
|
3896
|
+
type: object
|
|
3897
|
+
properties:
|
|
3898
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3899
|
+
roleName: { type: string }
|
|
3900
|
+
grantedBy: { type: string }
|
|
3901
|
+
grantedAt: { type: string, format: date-time }
|
|
3902
|
+
expiresAt: { type: string, format: date-time, description: Effective expiry; absent when long-term or group-provided. }
|
|
3903
|
+
viaGroup: { type: string }
|
|
3904
|
+
viaGroups: { type: array, items: { type: string } }
|
|
3905
|
+
required: [accountNumber, roleName]
|
|
3906
|
+
BulkAssignResult:
|
|
3907
|
+
type: object
|
|
3908
|
+
properties:
|
|
3909
|
+
userId: { type: string }
|
|
3910
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3911
|
+
roleName: { type: string }
|
|
3912
|
+
status: { type: string, enum: [GRANTED, ALREADY_HAD, FAILED] }
|
|
3913
|
+
message: { type: string }
|
|
3914
|
+
required: [userId, accountNumber, roleName, status]
|
|
3915
|
+
BulkRevokeResult:
|
|
3916
|
+
type: object
|
|
3917
|
+
properties:
|
|
3918
|
+
userId: { type: string }
|
|
3919
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3920
|
+
roleName: { type: string }
|
|
3921
|
+
status: { type: string, enum: [REVOKED, SKIPPED, FAILED] }
|
|
3922
|
+
message: { type: string }
|
|
3923
|
+
required: [userId, accountNumber, roleName, status]
|
|
3924
|
+
|
|
3925
|
+
User:
|
|
3926
|
+
type: object
|
|
3927
|
+
properties:
|
|
3928
|
+
userId: { type: string, description: "Cognito `sub` — the stable id grants are keyed by." }
|
|
3929
|
+
email: { type: string }
|
|
3930
|
+
admin: { type: boolean }
|
|
3931
|
+
pendingInvite: { type: boolean, description: Invited and never signed in — still on the temporary password, and not seen through a federated sign-in either. }
|
|
3932
|
+
lastSeenAt: { type: string, format: date-time }
|
|
3933
|
+
claims:
|
|
3934
|
+
type: object
|
|
3935
|
+
additionalProperties: { type: string }
|
|
3936
|
+
description: "Federated claims on the user, keyed by the config `claims` key (e.g. `gid`). Only when at least one is set."
|
|
3937
|
+
roleCount: { type: integer, minimum: 0, description: "Every role the user holds; `roles` carries at most 50 of them in the listing." }
|
|
3938
|
+
resourceCount: { type: integer, minimum: 0, description: "Every resource the user holds; `resources` carries at most 50 of them in the listing." }
|
|
3939
|
+
roleNames: { type: array, items: { type: string }, description: "Distinct role names over every role held (listing only) — complete where `roles` is cut." }
|
|
3940
|
+
groupNames: { type: array, items: { type: string }, description: Distinct team names over every role and resource held (listing only). }
|
|
3941
|
+
roles:
|
|
3942
|
+
type: array
|
|
3943
|
+
items:
|
|
3944
|
+
type: object
|
|
3945
|
+
properties:
|
|
3946
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3947
|
+
roleName: { type: string }
|
|
3948
|
+
direct: { type: boolean }
|
|
3949
|
+
groups: { type: array, items: { type: string }, description: Names of the user's groups whose bundle also grants it. }
|
|
3950
|
+
required: [accountNumber, roleName, direct, groups]
|
|
3951
|
+
resources:
|
|
3952
|
+
type: array
|
|
3953
|
+
items:
|
|
3954
|
+
type: object
|
|
3955
|
+
properties:
|
|
3956
|
+
resourceId: { type: string }
|
|
3957
|
+
name: { type: string }
|
|
3958
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
3959
|
+
direct: { type: boolean }
|
|
3960
|
+
groups: { type: array, items: { type: string } }
|
|
3961
|
+
required: [resourceId, name, direct, groups]
|
|
3962
|
+
required: [userId, email, admin, pendingInvite, roles, resources]
|
|
3963
|
+
BulkCreateResult:
|
|
3964
|
+
type: object
|
|
3965
|
+
properties:
|
|
3966
|
+
email: { type: string }
|
|
3967
|
+
status: { type: string, enum: [CREATED, FAILED] }
|
|
3968
|
+
userId: { type: string }
|
|
3969
|
+
signupLink: { type: string, description: "On CREATED rows when `sendEmail` was `false`." }
|
|
3970
|
+
message: { type: string }
|
|
3971
|
+
required: [email, status]
|
|
3972
|
+
BulkDeleteResult:
|
|
3973
|
+
type: object
|
|
3974
|
+
properties:
|
|
3975
|
+
userId: { type: string }
|
|
3976
|
+
status: { type: string, enum: [DELETED, FAILED] }
|
|
3977
|
+
message: { type: string }
|
|
3978
|
+
required: [userId, status]
|
|
3979
|
+
|
|
3980
|
+
ServiceUser:
|
|
3981
|
+
type: object
|
|
3982
|
+
properties:
|
|
3983
|
+
clientId: { type: string }
|
|
3984
|
+
name: { type: string }
|
|
3985
|
+
createdAt: { type: string, format: date-time }
|
|
3986
|
+
createdBy: { type: string }
|
|
3987
|
+
lastUsedAt: { type: string, format: date-time }
|
|
3988
|
+
secretCreatedAt: { type: string, format: date-time }
|
|
3989
|
+
reviewedAt: { type: string, format: date-time }
|
|
3990
|
+
roles: { type: array, items: { $ref: "#/components/schemas/UserGrant" } }
|
|
3991
|
+
previous:
|
|
3992
|
+
type: object
|
|
3993
|
+
description: Mid-rotation — the replaced client that still works.
|
|
3994
|
+
properties:
|
|
3995
|
+
clientId: { type: string }
|
|
3996
|
+
rotatedAt: { type: string, format: date-time }
|
|
3997
|
+
lastUsedAt: { type: string, format: date-time }
|
|
3998
|
+
required: [clientId]
|
|
3999
|
+
required: [clientId, name, createdAt, createdBy, roles]
|
|
4000
|
+
ServiceUserWithSecret:
|
|
4001
|
+
type: object
|
|
4002
|
+
properties:
|
|
4003
|
+
serviceUser: { $ref: "#/components/schemas/ServiceUser" }
|
|
4004
|
+
clientSecret: { type: string, description: Returned exactly once. }
|
|
4005
|
+
required: [serviceUser, clientSecret]
|
|
4006
|
+
|
|
4007
|
+
GroupInput:
|
|
4008
|
+
type: object
|
|
4009
|
+
properties:
|
|
4010
|
+
name: { type: string, minLength: 1, maxLength: 64 }
|
|
4011
|
+
description: { type: string, maxLength: 500 }
|
|
4012
|
+
roles: { type: array, items: { $ref: "#/components/schemas/RoleRef" } }
|
|
4013
|
+
resources: { type: array, items: { type: string }, description: Resource ids. }
|
|
4014
|
+
Group:
|
|
4015
|
+
type: object
|
|
4016
|
+
properties:
|
|
4017
|
+
groupId: { type: string }
|
|
4018
|
+
name: { type: string }
|
|
4019
|
+
description: { type: string }
|
|
4020
|
+
roles: { type: array, items: { $ref: "#/components/schemas/RoleRef" }, description: "In the list, at most 50 of them; `roleCount` is the total and GET /admin/groups/{groupId} carries all." }
|
|
4021
|
+
roleCount: { type: integer, minimum: 0 }
|
|
4022
|
+
resources: { type: array, items: { type: string }, description: Resource ids. }
|
|
4023
|
+
plugins:
|
|
4024
|
+
type: array
|
|
4025
|
+
description: Plugin permissions in the bundle.
|
|
4026
|
+
items:
|
|
4027
|
+
type: object
|
|
4028
|
+
properties:
|
|
4029
|
+
pluginId: { type: string }
|
|
4030
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
4031
|
+
permission: { type: string, enum: [user, admin] }
|
|
4032
|
+
required: [pluginId, accountNumber, permission]
|
|
4033
|
+
members: { type: array, items: { type: string }, description: Cognito subs, sorted. }
|
|
4034
|
+
createdAt: { type: string, format: date-time }
|
|
4035
|
+
createdBy: { type: string }
|
|
4036
|
+
required: [groupId, name, roles, resources, plugins, members, createdAt, createdBy]
|
|
4037
|
+
GroupView:
|
|
4038
|
+
type: object
|
|
4039
|
+
properties:
|
|
4040
|
+
groupId: { type: string }
|
|
4041
|
+
name: { type: string }
|
|
4042
|
+
description: { type: string }
|
|
4043
|
+
roles: { type: array, items: { $ref: "#/components/schemas/RoleRef" } }
|
|
4044
|
+
resources:
|
|
4045
|
+
type: array
|
|
4046
|
+
items:
|
|
4047
|
+
type: object
|
|
4048
|
+
properties:
|
|
4049
|
+
resourceId: { type: string }
|
|
4050
|
+
name: { type: string }
|
|
4051
|
+
required: [resourceId, name]
|
|
4052
|
+
members:
|
|
4053
|
+
type: array
|
|
4054
|
+
items:
|
|
4055
|
+
type: object
|
|
4056
|
+
properties:
|
|
4057
|
+
userId: { type: string }
|
|
4058
|
+
email: { type: string }
|
|
4059
|
+
required: [userId, email]
|
|
4060
|
+
createdAt: { type: string, format: date-time }
|
|
4061
|
+
createdBy: { type: string }
|
|
4062
|
+
required: [groupId, name, roles, resources, members, createdAt, createdBy]
|
|
4063
|
+
GroupEnvelope:
|
|
4064
|
+
type: object
|
|
4065
|
+
properties:
|
|
4066
|
+
group: { $ref: "#/components/schemas/Group" }
|
|
4067
|
+
required: [group]
|
|
4068
|
+
GroupRoleChange:
|
|
4069
|
+
type: object
|
|
4070
|
+
description: One role in or out of a bundle — what changed, never the bundle itself.
|
|
4071
|
+
properties:
|
|
4072
|
+
groupId: { type: string }
|
|
4073
|
+
name: { type: string }
|
|
4074
|
+
role: { $ref: "#/components/schemas/GroupRoleRef" }
|
|
4075
|
+
added: { type: boolean, description: "False when the role was already in the bundle." }
|
|
4076
|
+
required: [groupId, name, role, added]
|
|
4077
|
+
GroupRolesBulkResult:
|
|
4078
|
+
type: object
|
|
4079
|
+
properties:
|
|
4080
|
+
matched: { type: integer, description: Accounts matching the filter that have the role. }
|
|
4081
|
+
added: { type: integer, description: Rows written (absent on a dry run). }
|
|
4082
|
+
skipped: { type: integer, description: Matches already in the bundle (absent on a dry run). }
|
|
4083
|
+
remaining: { type: integer, description: "Matches not yet written: one call writes at most 500, call again until this is 0 (absent on a dry run)." }
|
|
4084
|
+
group: { $ref: "#/components/schemas/Group" }
|
|
4085
|
+
required: [matched]
|
|
4086
|
+
|
|
4087
|
+
Resource:
|
|
4088
|
+
type: object
|
|
4089
|
+
properties:
|
|
4090
|
+
resourceId: { type: string }
|
|
4091
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
4092
|
+
name: { type: string }
|
|
4093
|
+
type: { $ref: "#/components/schemas/ResourceType" }
|
|
4094
|
+
cidr: { type: string, description: "Always `a.b.c.d/nn` with 24 ≤ nn ≤ 32." }
|
|
4095
|
+
ports: { type: array, items: { type: integer } }
|
|
4096
|
+
dnsName: { type: string, description: Connect name shown to users; the reconciler re-resolves it each pass. }
|
|
4097
|
+
sshUser: { type: string }
|
|
4098
|
+
securityGroupId: { type: string, description: When set, the reconciler keeps a connector ingress rule in it. }
|
|
4099
|
+
description: { type: string }
|
|
4100
|
+
createdAt: { type: string, format: date-time }
|
|
4101
|
+
createdBy: { type: string }
|
|
4102
|
+
required: [resourceId, accountNumber, name, type, cidr, ports, createdAt, createdBy]
|
|
4103
|
+
ResourceCreate:
|
|
4104
|
+
type: object
|
|
4105
|
+
properties:
|
|
4106
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
4107
|
+
name: { type: string }
|
|
4108
|
+
type: { $ref: "#/components/schemas/ResourceType" }
|
|
4109
|
+
cidr: { type: string, description: Bare IPv4 or /16–/32 CIDR. }
|
|
4110
|
+
ports: { type: array, items: { type: integer, minimum: 1, maximum: 65535 }, minItems: 1 }
|
|
4111
|
+
dnsName: { type: string }
|
|
4112
|
+
sshUser: { type: string }
|
|
4113
|
+
securityGroupId: { type: string }
|
|
4114
|
+
description: { type: string }
|
|
4115
|
+
required: [accountNumber, name, type, cidr, ports]
|
|
4116
|
+
ResourcePatch:
|
|
4117
|
+
type: object
|
|
4118
|
+
description: At least one field.
|
|
4119
|
+
properties:
|
|
4120
|
+
name: { type: string }
|
|
4121
|
+
type: { $ref: "#/components/schemas/ResourceType" }
|
|
4122
|
+
cidr: { type: string }
|
|
4123
|
+
ports: { type: array, items: { type: integer, minimum: 1, maximum: 65535 }, minItems: 1 }
|
|
4124
|
+
dnsName: { type: string }
|
|
4125
|
+
sshUser: { type: string }
|
|
4126
|
+
securityGroupId: { type: string }
|
|
4127
|
+
description: { type: string }
|
|
4128
|
+
ResourceEnvelope:
|
|
4129
|
+
type: object
|
|
4130
|
+
properties:
|
|
4131
|
+
resource: { $ref: "#/components/schemas/Resource" }
|
|
4132
|
+
required: [resource]
|
|
4133
|
+
ResourceGrantee:
|
|
4134
|
+
type: object
|
|
4135
|
+
properties:
|
|
4136
|
+
userId: { type: string }
|
|
4137
|
+
email: { type: string }
|
|
4138
|
+
grantedBy: { type: string }
|
|
4139
|
+
grantedAt: { type: string, format: date-time }
|
|
4140
|
+
expiresAt: { type: string, format: date-time }
|
|
4141
|
+
direct: { type: boolean }
|
|
4142
|
+
viaGroup: { type: string }
|
|
4143
|
+
viaGroups: { type: array, items: { type: string } }
|
|
4144
|
+
required: [userId, email, direct, viaGroups]
|
|
4145
|
+
UserResourceGrant:
|
|
4146
|
+
type: object
|
|
4147
|
+
properties:
|
|
4148
|
+
resourceId: { type: string }
|
|
4149
|
+
grantedBy: { type: string }
|
|
4150
|
+
grantedAt: { type: string, format: date-time }
|
|
4151
|
+
expiresAt: { type: string, format: date-time }
|
|
4152
|
+
viaGroup: { type: string }
|
|
4153
|
+
viaGroups: { type: array, items: { type: string } }
|
|
4154
|
+
required: [resourceId]
|
|
4155
|
+
UserResourceGrantNamed:
|
|
4156
|
+
allOf:
|
|
4157
|
+
- $ref: "#/components/schemas/UserResourceGrant"
|
|
4158
|
+
- type: object
|
|
4159
|
+
properties:
|
|
4160
|
+
resourceName: { type: string }
|
|
4161
|
+
required: [resourceName]
|
|
4162
|
+
|
|
4163
|
+
ReconcilerStatus:
|
|
4164
|
+
type: object
|
|
4165
|
+
properties:
|
|
4166
|
+
at: { type: [string, "null"], format: date-time, description: Oldest site pass; `null` = never ran. }
|
|
4167
|
+
resources:
|
|
4168
|
+
type: object
|
|
4169
|
+
description: Keyed by resourceId.
|
|
4170
|
+
additionalProperties:
|
|
4171
|
+
type: object
|
|
4172
|
+
properties:
|
|
4173
|
+
status: { type: string }
|
|
4174
|
+
users: { type: integer }
|
|
4175
|
+
sg: { type: string, description: "SG-manager verdict for the resource's security group: ok, not-found, invalid, error, other-vpc (the group is in none of the account's connector VPCs), sg-sync-failed." }
|
|
4176
|
+
sgId: { type: string }
|
|
4177
|
+
addr: { type: string, enum: [dns, dns-stale] }
|
|
4178
|
+
addrIp: { type: string }
|
|
4179
|
+
addrName: { type: string }
|
|
4180
|
+
required: [status]
|
|
4181
|
+
staleConnectors: { type: array, items: { type: string } }
|
|
4182
|
+
resourcesLive: { type: integer }
|
|
4183
|
+
rules: { type: integer }
|
|
4184
|
+
shares:
|
|
4185
|
+
type: object
|
|
4186
|
+
description: Dev shares keyed by shareId — `live` (users = enrolled grantees named) or why not (`owner-not-enrolled`, `no-grantees`, `no-enrolled-grantees`, `invalid-port`).
|
|
4187
|
+
additionalProperties:
|
|
4188
|
+
type: object
|
|
4189
|
+
properties:
|
|
4190
|
+
status: { type: string }
|
|
4191
|
+
users: { type: integer }
|
|
4192
|
+
required: [status]
|
|
4193
|
+
sharesLive: { type: integer }
|
|
4194
|
+
sites:
|
|
4195
|
+
type: object
|
|
4196
|
+
additionalProperties:
|
|
4197
|
+
type: object
|
|
4198
|
+
properties:
|
|
4199
|
+
at: { type: [string, "null"], format: date-time }
|
|
4200
|
+
staleConnectors: { type: array, items: { type: string } }
|
|
4201
|
+
resourcesLive: { type: integer }
|
|
4202
|
+
rules: { type: integer }
|
|
4203
|
+
sharesLive: { type: integer }
|
|
4204
|
+
required: [at, staleConnectors, resourcesLive, rules]
|
|
4205
|
+
connectors:
|
|
4206
|
+
type: array
|
|
4207
|
+
items:
|
|
4208
|
+
type: object
|
|
4209
|
+
properties:
|
|
4210
|
+
siteId: { type: string }
|
|
4211
|
+
account: { type: string }
|
|
4212
|
+
name: { type: string }
|
|
4213
|
+
vpcName: { type: string, description: Which of the account's connector VPCs (its config name); absent = the unnamed one. }
|
|
4214
|
+
nodeId: { type: string }
|
|
4215
|
+
trusted: { type: boolean }
|
|
4216
|
+
online: { type: boolean }
|
|
4217
|
+
lastSeen: { type: string, format: date-time }
|
|
4218
|
+
advertisedRoutes: { type: array, items: { type: string } }
|
|
4219
|
+
approvedRoutes: { type: array, items: { type: string } }
|
|
4220
|
+
required: [siteId, account, name, trusted, online, advertisedRoutes, approvedRoutes]
|
|
4221
|
+
devices:
|
|
4222
|
+
type: object
|
|
4223
|
+
description: Keyed by user sub.
|
|
4224
|
+
additionalProperties:
|
|
4225
|
+
type: object
|
|
4226
|
+
properties:
|
|
4227
|
+
count: { type: integer }
|
|
4228
|
+
online: { type: boolean }
|
|
4229
|
+
lastSeen: { type: string, format: date-time }
|
|
4230
|
+
sites: { type: array, items: { type: string } }
|
|
4231
|
+
required: [count, online, sites]
|
|
4232
|
+
required: [at, resources, staleConnectors, resourcesLive, rules, connectors, devices]
|
|
4233
|
+
|
|
4234
|
+
ActivityActor:
|
|
4235
|
+
type: object
|
|
4236
|
+
properties:
|
|
4237
|
+
kind: { type: string, enum: [user, service, system] }
|
|
4238
|
+
id: { type: string, description: Cognito sub, app client id, or `system:<job>`. }
|
|
4239
|
+
name: { type: string, description: The live directory name when the caller still exists, else the write-time snapshot. }
|
|
4240
|
+
claims:
|
|
4241
|
+
type: object
|
|
4242
|
+
additionalProperties: { type: string }
|
|
4243
|
+
deleted: { type: boolean, description: Present when the caller is no longer in the directory. }
|
|
4244
|
+
required: [kind, id]
|
|
4245
|
+
ActivitySubject:
|
|
4246
|
+
type: object
|
|
4247
|
+
properties:
|
|
4248
|
+
kind: { type: string, enum: [user, group, serviceUser] }
|
|
4249
|
+
id: { type: string }
|
|
4250
|
+
name: { type: string }
|
|
4251
|
+
deleted: { type: boolean }
|
|
4252
|
+
required: [kind, id]
|
|
4253
|
+
ActivityEventView:
|
|
4254
|
+
type: object
|
|
4255
|
+
description: One recorded action. `action` is `object.verb` (role.grant, request.approve, credentials.vend, vpn.connect, admin.access, …); `outcome` says whether it happened.
|
|
4256
|
+
properties:
|
|
4257
|
+
eventId: { type: string }
|
|
4258
|
+
category: { type: string, enum: [access, request, vend, network, catalog, users, auth] }
|
|
4259
|
+
action: { type: string }
|
|
4260
|
+
outcome: { type: string, enum: [OK, DENIED, FAILED] }
|
|
4261
|
+
reason: { type: string, description: Caller-safe cause on DENIED and FAILED rows. }
|
|
4262
|
+
actor: { $ref: "#/components/schemas/ActivityActor" }
|
|
4263
|
+
subject: { $ref: "#/components/schemas/ActivitySubject" }
|
|
4264
|
+
target: { type: string, description: "`role#<account>#<name>`, `resource#<id>`, `plugin#<id>#<account>#<permission>`, `share#<id>`, `group#<id>`, `user#<sub>`, `serviceuser#<id>`, `account#<n>`, `site#<id>`, `sg#<id>`, `route#<METHOD /path>`." }
|
|
4265
|
+
targetName: { type: string }
|
|
4266
|
+
accountNumber: { $ref: "#/components/schemas/AccountNumber" }
|
|
4267
|
+
details:
|
|
4268
|
+
type: object
|
|
4269
|
+
description: expiresAt, durationHours, note, via (ADMIN | GROUP | REAPPROVAL | CASCADE | OWNER | EXPIRY), groupId, requestId, batchId, changed (key → {from, to}), affected (up to 50 {userId, name, change}) + affectedCount, deniedReason, and action-specific keys.
|
|
4270
|
+
additionalProperties: true
|
|
4271
|
+
derived: { type: boolean, description: A per-user effective-access change the access diff wrote (access.gain / access.lose), linked to its batch's primary row. }
|
|
4272
|
+
at: { type: string, format: date-time }
|
|
4273
|
+
day: { type: string, description: UTC calendar day `YYYY-MM-DD`. }
|
|
4274
|
+
required: [eventId, category, action, outcome, actor, at, day]
|
|
4275
|
+
ActivityPage:
|
|
4276
|
+
type: object
|
|
4277
|
+
properties:
|
|
4278
|
+
events:
|
|
4279
|
+
type: array
|
|
4280
|
+
items: { $ref: "#/components/schemas/ActivityEventView" }
|
|
4281
|
+
from: { type: string, format: date-time }
|
|
4282
|
+
to: { type: string, format: date-time }
|
|
4283
|
+
nextBefore: { type: string, format: date-time, description: Present when the page filled up — pass as `before` (with `skip`) to continue. }
|
|
4284
|
+
required: [events, from, to]
|