From 1fe5d73483ab370631b7240d820a3e3f43f6cdf1 Mon Sep 17 00:00:00 2001 From: C0ffeeCode Date: Mon, 24 Mar 2025 19:45:44 +0100 Subject: [PATCH] Feat (kv2): kv2 data access (no metadata) --- ...07389c90453b5d3ad92344272838958ab28e.json} | 4 +- ...ca5bbd5220b909b6c1b5eb5c77ce0dd2259e4.json | 44 + Cargo.lock | 195 +- Cargo.toml | 2 +- Containerfile | 12 +- Justfile | 2 +- go_client/TODO.md | 14 - go_client/main.go | 29 - {go_client => go_tests}/Containerfile | 0 {go_client => go_tests}/go.mod | 7 +- {go_client => go_tests}/go.sum | 22 +- go_tests/main.go | 26 + {go_client => go_tests}/tests/secret_test.go | 9 +- migrations/20240501152243_KvSecret.sql | 2 +- openapi-bao.json | 11464 ++++++++++++++++ src/engines/kv.rs | 277 +- src/engines/kv/data.rs | 215 + src/engines/kv/logic.rs | 56 - src/engines/kv/meta.rs | 26 + src/engines/kv/post_secret.sql | 2 +- src/engines/kv/structs.rs | 1 - 21 files changed, 11943 insertions(+), 466 deletions(-) rename .sqlx/{query-0b6d152060335c7c8cc6e781eac810a3fc1c2ad752e3f856a66e75b73b2ab3c6.json => query-844de8351a0ed204e2080857373507389c90453b5d3ad92344272838958ab28e.json} (74%) create mode 100644 .sqlx/query-919758dd0aee1053065d62d528bca5bbd5220b909b6c1b5eb5c77ce0dd2259e4.json delete mode 100644 go_client/TODO.md delete mode 100644 go_client/main.go rename {go_client => go_tests}/Containerfile (100%) rename {go_client => go_tests}/go.mod (87%) rename {go_client => go_tests}/go.sum (84%) create mode 100644 go_tests/main.go rename {go_client => go_tests}/tests/secret_test.go (94%) create mode 100644 openapi-bao.json create mode 100644 src/engines/kv/data.rs delete mode 100644 src/engines/kv/logic.rs create mode 100644 src/engines/kv/meta.rs diff --git a/.sqlx/query-0b6d152060335c7c8cc6e781eac810a3fc1c2ad752e3f856a66e75b73b2ab3c6.json b/.sqlx/query-844de8351a0ed204e2080857373507389c90453b5d3ad92344272838958ab28e.json similarity index 74% rename from .sqlx/query-0b6d152060335c7c8cc6e781eac810a3fc1c2ad752e3f856a66e75b73b2ab3c6.json rename to .sqlx/query-844de8351a0ed204e2080857373507389c90453b5d3ad92344272838958ab28e.json index 536b34c..1978cd7 100644 --- a/.sqlx/query-0b6d152060335c7c8cc6e781eac810a3fc1c2ad752e3f856a66e75b73b2ab3c6.json +++ b/.sqlx/query-844de8351a0ed204e2080857373507389c90453b5d3ad92344272838958ab28e.json @@ -1,6 +1,6 @@ { "db_name": "SQLite", - "query": "SELECT secret_data, created_time, deletion_time, version_number, secret_path\n FROM kv2_secret_version WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL\n ORDER BY version_number DESC LIMIT 1", + "query": "SELECT secret_data, created_time, deletion_time, version_number, secret_path\n FROM kv2_secret_version WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL\n ORDER BY version_number DESC LIMIT 1", "describe": { "columns": [ { @@ -40,5 +40,5 @@ false ] }, - "hash": "0b6d152060335c7c8cc6e781eac810a3fc1c2ad752e3f856a66e75b73b2ab3c6" + "hash": "844de8351a0ed204e2080857373507389c90453b5d3ad92344272838958ab28e" } diff --git a/.sqlx/query-919758dd0aee1053065d62d528bca5bbd5220b909b6c1b5eb5c77ce0dd2259e4.json b/.sqlx/query-919758dd0aee1053065d62d528bca5bbd5220b909b6c1b5eb5c77ce0dd2259e4.json new file mode 100644 index 0000000..56bd9cf --- /dev/null +++ b/.sqlx/query-919758dd0aee1053065d62d528bca5bbd5220b909b6c1b5eb5c77ce0dd2259e4.json @@ -0,0 +1,44 @@ +{ + "db_name": "SQLite", + "query": "SELECT secret_data, created_time, deletion_time, version_number, secret_path\n FROM kv2_secret_version WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL\n AND version_number = $3", + "describe": { + "columns": [ + { + "name": "secret_data", + "ordinal": 0, + "type_info": "Text" + }, + { + "name": "created_time", + "ordinal": 1, + "type_info": "Datetime" + }, + { + "name": "deletion_time", + "ordinal": 2, + "type_info": "Datetime" + }, + { + "name": "version_number", + "ordinal": 3, + "type_info": "Integer" + }, + { + "name": "secret_path", + "ordinal": 4, + "type_info": "Text" + } + ], + "parameters": { + "Right": 3 + }, + "nullable": [ + false, + false, + true, + false, + false + ] + }, + "hash": "919758dd0aee1053065d62d528bca5bbd5220b909b6c1b5eb5c77ce0dd2259e4" +} diff --git a/Cargo.lock b/Cargo.lock index c2e87fd..c5c28d4 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -174,9 +174,9 @@ checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" [[package]] name = "base64ct" -version = "1.6.0" +version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c3c1a368f70d6cf7302d78f8f7093da241fb8e8807c05cc9e51a125895a6d5b" +checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" [[package]] name = "bitflags" @@ -210,9 +210,9 @@ checksum = "d71b6127be86fdcfddb610f7182ac57211d4b18a3e9c82eb2d17662f2227ad6a" [[package]] name = "cc" -version = "1.2.16" +version = "1.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "be714c154be609ec7f5dad223a33bf1482fff90472de28f7362806e6d4832b8c" +checksum = "1fcb57c740ae1daf453ae85f16e37396f672b039e00d9d866e07ddb24e328e3a" dependencies = [ "shlex", ] @@ -306,9 +306,9 @@ dependencies = [ [[package]] name = "deranged" -version = "0.3.11" +version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b42b6fa04a440b495c8b04d0e71b707c585f83cb9cb28cf8cd0d976c315e31b4" +checksum = "28cfac68e08048ae1883171632c2aef3ebc555621ae56fbccce1cbf22dd7f058" dependencies = [ "powerfmt", "serde", @@ -364,14 +364,14 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.6" +version = "0.11.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dcaee3d8e3cfc3fd92428d477bc97fc29ec8716d180c0d74c643bb26166660e0" +checksum = "c3716d7a920fb4fac5d84e9d4bce8ceb321e9414b4409da61b07b75c1e3d0697" dependencies = [ "anstream", "anstyle", "env_filter", - "humantime", + "jiff", "log", ] @@ -438,9 +438,9 @@ checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" [[package]] name = "foldhash" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a0d2fde1f7b3d48b8395d5f2de76c18a528bd6a9cdde438df747bfcba3e05d6f" +checksum = "d9c4f5dac5e15c24eb999c26181a6ca40b39fe946cbe4c263c7209467bc83af2" [[package]] name = "form_urlencoded" @@ -546,14 +546,14 @@ dependencies = [ [[package]] name = "getrandom" -version = "0.3.1" +version = "0.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "43a49c392881ce6d5c3b8cb70f98717b7c07aabbdff06687b9030dbfbe2725f8" +checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0" dependencies = [ "cfg-if", "libc", - "wasi 0.13.3+wasi-0.2.2", - "windows-targets 0.52.6", + "r-efi", + "wasi 0.14.2+wasi-0.2.4", ] [[package]] @@ -623,9 +623,9 @@ dependencies = [ [[package]] name = "http" -version = "1.2.0" +version = "1.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f16ca2af56261c99fba8bac40a10251ce8188205a4c448fbb745a2e4daa76fea" +checksum = "f4a85d31aea989eead29a3aaf9e1115a180df8282431156e533de47660892565" dependencies = [ "bytes", "fnv", @@ -644,12 +644,12 @@ dependencies = [ [[package]] name = "http-body-util" -version = "0.1.2" +version = "0.1.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" +checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", - "futures-util", + "futures-core", "http", "http-body", "pin-project-lite", @@ -667,12 +667,6 @@ version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" -[[package]] -name = "humantime" -version = "2.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9a3a5bfb195931eeb336b2a7b4d761daec841b97f947d34394601737a7bba5e4" - [[package]] name = "hyper" version = "1.6.0" @@ -849,9 +843,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.7.1" +version = "2.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8c9c992b02b5b4c94ea26e32fe5bccb7aa7d9f390ab5c1221ff895bc7ea8b652" +checksum = "3954d50fe15b02142bf25d3b8bdadb634ec3948f103d04ffe3031bc8fe9d7058" dependencies = [ "equivalent", "hashbrown", @@ -869,6 +863,30 @@ version = "1.0.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c" +[[package]] +name = "jiff" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c102670231191d07d37a35af3eb77f1f0dbf7a71be51a962dcd57ea607be7260" +dependencies = [ + "jiff-static", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", +] + +[[package]] +name = "jiff-static" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4cdde31a9d349f1b1f51a0b3714a5940ac022976f4b49485fc04be052b183b4c" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + [[package]] name = "json-patch" version = "4.0.0" @@ -902,9 +920,9 @@ dependencies = [ [[package]] name = "libc" -version = "0.2.170" +version = "0.2.171" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "875b3680cb2f8f71bdcf9a30f38d48282f5d3c95cbf9b3fa57269bb5d5c06828" +checksum = "c19937216e9d3aa9956d9bb8dfc0b0c8beb6058fc4f7a4dc4d850edf86a237d6" [[package]] name = "libm" @@ -925,9 +943,9 @@ dependencies = [ [[package]] name = "linux-raw-sys" -version = "0.4.15" +version = "0.9.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d26c52dbd32dccf2d10cac7725f8eae5296885fb5703b261f7d0a0739ec807ab" +checksum = "fe7db12097d22ec582439daf8618b8fdd1a7bef6270e9af3b1ebcd30893cf413" [[package]] name = "litemap" @@ -947,9 +965,9 @@ dependencies = [ [[package]] name = "log" -version = "0.4.26" +version = "0.4.27" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "30bde2b3dc3671ae49d8e2e9f044c7c005836e7a023ee57cffa25ab82764bb9e" +checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94" [[package]] name = "matchit" @@ -1063,9 +1081,9 @@ dependencies = [ [[package]] name = "once_cell" -version = "1.20.3" +version = "1.21.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "945462a4b81e43c4e3ba96bd7b49d834c6f61198356aa858733bc4acf3cbe62e" +checksum = "d75b0bedcc4fe52caa0e03d9f1151a323e4aa5e2d78ba3580400cd3c9e2bc4bc" [[package]] name = "parking" @@ -1150,6 +1168,21 @@ version = "0.3.32" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c" +[[package]] +name = "portable-atomic" +version = "1.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "350e9b48cbc6b0e028b0473b114454c6316e57336ee184ceab6e53f72c178b3e" + +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -1158,9 +1191,9 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "ppv-lite86" -version = "0.2.20" +version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "77957b295656769bb8ad2b6a6b09d897d94f05c41b069aede1fcdaa675eaea04" +checksum = "85eae3c4ed2f50dcfe72643da4befc30deadb458a9b590d720cde2f2b1e97da9" dependencies = [ "zerocopy", ] @@ -1176,13 +1209,19 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.39" +version = "1.0.40" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c1f1914ce909e1658d9907913b4b91947430c7d9be598b15a1912935b8c04801" +checksum = "1885c039570dc00dcb4ff087a89e185fd56bae234ddc7f056a945bf36467248d" dependencies = [ "proc-macro2", ] +[[package]] +name = "r-efi" +version = "5.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5" + [[package]] name = "rand" version = "0.8.5" @@ -1253,9 +1292,9 @@ checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "ring" -version = "0.17.12" +version = "0.17.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ed9b823fa29b721a59671b41d6b06e66b29e0628e207e8b1c3ceeda701ec928d" +checksum = "a4689e6c2294d81e88dc6261c768b63bc4fcdb852be6d1352498b114f61383b7" dependencies = [ "cc", "cfg-if", @@ -1267,9 +1306,9 @@ dependencies = [ [[package]] name = "rsa" -version = "0.9.7" +version = "0.9.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47c75d7c5c6b673e58bf54d8544a9f432e3a925b0e80f7cd3602ab5c50c55519" +checksum = "78928ac1ed176a5ca1d17e578a1825f3d81ca54cf41053a592584b020cfd691b" dependencies = [ "const-oid", "digest", @@ -1293,9 +1332,9 @@ checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" [[package]] name = "rustix" -version = "0.38.44" +version = "1.0.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fdb5bc1ae2baa591800df16c9ca78619bf65c0488b41b96ccec5d11220d8c154" +checksum = "e56a18552996ac8d29ecc3b190b4fdbb2d91ca4ec396de7bbffaf43f3d637e96" dependencies = [ "bitflags", "errno", @@ -1306,9 +1345,9 @@ dependencies = [ [[package]] name = "rustls" -version = "0.23.23" +version = "0.23.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "47796c98c480fce5406ef69d1c76378375492c3b0a0de587be0c1d9feb12f395" +checksum = "822ee9188ac4ec04a2f0531e55d035fb2de73f18b41a63c70c2712503b6fb13c" dependencies = [ "once_cell", "ring", @@ -1335,9 +1374,9 @@ checksum = "917ce264624a4b4db1c364dcc35bfca9ded014d0a958cd47ad3e960e988ea51c" [[package]] name = "rustls-webpki" -version = "0.102.8" +version = "0.103.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "64ca1bc8749bd4cf37b5ce386cc146580777b4e8572c7b97baf22c83f444bee9" +checksum = "0aa4eeac2588ffff23e9d7a7e9b3f971c5fb5b7ebc9452745e0c232c64f83b2f" dependencies = [ "ring", "rustls-pki-types", @@ -1382,18 +1421,18 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "serde" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8dfc9d19bdbf6d17e22319da49161d5d0108e4188e8b680aef6299eed22df60" +checksum = "5f0e2c6ed6606019b4e29e69dbaba95b11854410e5347d525002456dbbb786b6" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.218" +version = "1.0.219" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f09503e191f4e797cb8aac08e9a4a4695c5edf6a2e70e376d961ddd5c969f82b" +checksum = "5b0276cf7f2c73365f7157c8123c21cd9a50fbbd844757af28ca1f5925fc2a00" dependencies = [ "proc-macro2", "quote", @@ -1747,9 +1786,9 @@ checksum = "13c2bddecc57b384dee18652358fb23172facb8a2c51ccc10d74c157bdea3292" [[package]] name = "syn" -version = "2.0.99" +version = "2.0.100" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e02e925281e18ffd9d640e234264753c43edc62d64b2d4cf898f1bc5e75f3fc2" +checksum = "b09a44accad81e1ba1cd74a32461ba89dee89095ba17b32f5d03683b1b1fc2a0" dependencies = [ "proc-macro2", "quote", @@ -1775,13 +1814,12 @@ dependencies = [ [[package]] name = "tempfile" -version = "3.17.1" +version = "3.19.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22e5a0acb1f3f55f65cc4a866c361b2fb2a0ff6366785ae6fbb5f85df07ba230" +checksum = "7437ac7763b9b123ccf33c338a5cc1bac6f69b45a136c19bdd8a65e3916435bf" dependencies = [ - "cfg-if", "fastrand", - "getrandom 0.3.1", + "getrandom 0.3.2", "once_cell", "rustix", "windows-sys 0.59.0", @@ -1829,9 +1867,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.39" +version = "0.3.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dad298b01a40a23aac4580b67e3dbedb7cc8402f3592d7f49469de2ea4aecdd8" +checksum = "8a7619e19bc266e0f9c5e6686659d394bc57973859340060a69221e57dbc0c40" dependencies = [ "deranged", "itoa", @@ -1844,15 +1882,15 @@ dependencies = [ [[package]] name = "time-core" -version = "0.1.3" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "765c97a5b985b7c11d7bc27fa927dc4fe6af3a6dfb021d28deb60d3bf51e76ef" +checksum = "c9e9a38711f559d9e3ce1cdb06dd7c5b8ea546bc90052da6d06bb76da74bb07c" [[package]] name = "time-macros" -version = "0.2.20" +version = "0.2.22" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e8093bc3e81c3bc5f7879de09619d06c9a5a5e45ca44dfeeb7225bae38005c5c" +checksum = "3526739392ec93fd8b359c8e98514cb3e8e021beb4e5f597b00a0221f8ed8a49" dependencies = [ "num-conv", "time-core", @@ -1885,9 +1923,9 @@ checksum = "1f3ccbac311fea05f86f61904b462b55fb3df8837a366dfc601a0161d0532f20" [[package]] name = "tokio" -version = "1.43.0" +version = "1.44.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3d61fa4ffa3de412bfea335c6ecff681de2b609ba3c77ef3e00e521813a9ed9e" +checksum = "f382da615b842244d4b8738c82ed1275e6c5dd90c459a30941cd07080b06c91a" dependencies = [ "backtrace", "bytes", @@ -2071,9 +2109,9 @@ checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" [[package]] name = "wasi" -version = "0.13.3+wasi-0.2.2" +version = "0.14.2+wasi-0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "26816d2e1a4a36a2940b96c5296ce403917633dff8f3440e9b236ed6f6bacad2" +checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3" dependencies = [ "wit-bindgen-rt", ] @@ -2095,9 +2133,9 @@ dependencies = [ [[package]] name = "whoami" -version = "1.5.2" +version = "1.6.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "372d5b87f58ec45c384ba03563b03544dc5fadc3983e434b286913f5b4a9bb6d" +checksum = "6994d13118ab492c3c80c1f81928718159254c53c472bf9ce36f8dae4add02a7" dependencies = [ "redox_syscall", "wasite", @@ -2253,9 +2291,9 @@ checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" [[package]] name = "wit-bindgen-rt" -version = "0.33.0" +version = "0.39.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3268f3d866458b787f390cf61f4bbb563b922d091359f9608842999eaee3943c" +checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1" dependencies = [ "bitflags", ] @@ -2298,19 +2336,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.7.35" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b9b4fd18abc82b8136838da5d50bae7bdea537c574d8dc1a34ed098d6c166f0" +checksum = "2586fea28e186957ef732a5f8b3be2da217d65c5969d4b1e17f973ebbe876879" dependencies = [ - "byteorder", "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.7.35" +version = "0.8.24" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa4f8080344d4671fb4e831a13ad1e68092748387dfc4f55e356242fae12ce3e" +checksum = "a996a8f63c5c4448cd959ac1bab0aaa3306ccfd060472f85943ee0750f0169be" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 45dbc17..bed1b56 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,7 +1,7 @@ [package] name = "rvault-server" version = "0.1.0" -edition = "2021" +edition = "2024" [dependencies] log = "0.4.21" diff --git a/Containerfile b/Containerfile index d2165d0..ba283db 100644 --- a/Containerfile +++ b/Containerfile @@ -1,9 +1,12 @@ -FROM docker.io/library/rust:1-alpine3.19 AS builder +ARG alpine_version=3.21 + +FROM docker.io/library/rust:1-alpine${alpine_version} AS builder WORKDIR /src RUN apk add --no-cache musl-dev RUN cargo install sqlx-cli --no-default-features --features sqlite +# Required for compile-time schemata checks of migrations ENV DATABASE_URL=sqlite:/tmp/rvault.db RUN touch /tmp/rvault.db @@ -13,6 +16,7 @@ RUN --mount=type=cache,target=/usr/local/cargo/registry \ cargo fetch --locked --target $(rustc -vV | sed -n 's|host: ||p') && \ rm src/main.rs +# Required for compile-time checks of query - database-schema compatibility COPY migrations migrations RUN cargo sqlx migrate run @@ -20,9 +24,9 @@ COPY src src RUN --mount=type=cache,target=/usr/local/cargo/registry \ cargo build --release --locked -FROM docker.io/library/alpine:3.19 AS runner +FROM docker.io/library/alpine:${alpine_version} AS runner # FROM scratch AS runner -COPY --from=builder /src/target/release/rvault-server /usr/local/bin/rvault-server +COPY --from=builder /src/target/release/rvault-server /usr/bin/rvault-server -CMD ["/usr/local/bin/rvault-server"] +CMD ["/usr/bin/rvault-server"] diff --git a/Justfile b/Justfile index c6b8c2e..8783fdd 100644 --- a/Justfile +++ b/Justfile @@ -1,6 +1,6 @@ build_tests: - podman build -t rvault-go-tests -f ./go_client/Containerfile ./go_client + podman build -t rvault-go-tests -f ./go_tests/Containerfile ./go_tests run_tests: build_tests podman run --rm -it --net=host rvault-go-tests diff --git a/go_client/TODO.md b/go_client/TODO.md deleted file mode 100644 index 5b618bf..0000000 --- a/go_client/TODO.md +++ /dev/null @@ -1,14 +0,0 @@ -# Testing module proposals - -- Basic API calls - - Login/logout -- kv IO test module -- Token - - Lookup - - Generation - -(- TLS module) -(- Auth module) - - -==> Nur KvV2 testen \ No newline at end of file diff --git a/go_client/main.go b/go_client/main.go deleted file mode 100644 index 060e2f8..0000000 --- a/go_client/main.go +++ /dev/null @@ -1,29 +0,0 @@ -package main - -import ( - "log" - "log/slog" - "time" - - "github.com/hashicorp/vault-client-go" -) - -// vault cmd args: >vault server -dev -dev-root-token-id="my-token" - -func main() { - slog.Info("run tests in tests/ with >go test") - // prepare a client with the given base address - client, err := vault.New( - vault.WithAddress("http://localhost:8200"), - vault.WithRequestTimeout(30*time.Second), - ) - if err != nil { - log.Fatal(err) - } - log.Println("client prepared") - - // authenticate with a root token (insecure) - if err := client.SetToken("my-token"); err != nil { - log.Fatal(err) - } -} diff --git a/go_client/Containerfile b/go_tests/Containerfile similarity index 100% rename from go_client/Containerfile rename to go_tests/Containerfile diff --git a/go_client/go.mod b/go_tests/go.mod similarity index 87% rename from go_client/go.mod rename to go_tests/go.mod index 226942a..8b80534 100644 --- a/go_client/go.mod +++ b/go_tests/go.mod @@ -2,9 +2,12 @@ module github.com/C0ffeeCode/rvault/go_client go 1.21.9 -require github.com/hashicorp/vault-client-go v0.4.3 +// require github.com/hashicorp/vault-client-go v0.4.3 -require github.com/hashicorp/vault/api v1.16.0 +require ( + github.com/hashicorp/vault-client-go v0.4.3 + github.com/hashicorp/vault/api v1.16.0 +) require ( github.com/cenkalti/backoff/v4 v4.3.0 // indirect diff --git a/go_client/go.sum b/go_tests/go.sum similarity index 84% rename from go_client/go.sum rename to go_tests/go.sum index 8e727da..84388b5 100644 --- a/go_client/go.sum +++ b/go_tests/go.sum @@ -6,20 +6,24 @@ github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSs github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/go-jose/go-jose/v4 v4.0.1 h1:QVEPDE3OluqXBQZDcnNvQrInro2h0e4eqNbnZSWqS6U= github.com/go-jose/go-jose/v4 v4.0.1/go.mod h1:WVf9LFMHh/QVrmqrOfqun0C45tMe3RoiKJMPvgWwLfY= +github.com/go-test/deep v1.0.2 h1:onZX1rnHT3Wv6cqNgYyFOOlgVKJrksuCMCRvJStbMYw= +github.com/go-test/deep v1.0.2/go.mod h1:wGDj63lr65AM2AQyKZd/NYHGb0R+1RLqB8NKt3aSFNA= +github.com/google/go-cmp v0.5.9 h1:O2Tfq5qg4qc4AmwVlvv0oLiVAGB7enBSJ2x2DqQFi38= +github.com/google/go-cmp v0.5.9/go.mod h1:17dUlkBOakJ0+DkrSSNjCkIjxS6bF9zb3elmeNGIjoY= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/errwrap v1.1.0 h1:OxrOeh75EUXMY8TBjag2fzXGZ40LB6IKw45YeGUDY2I= github.com/hashicorp/errwrap v1.1.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= -github.com/hashicorp/go-hclog v0.9.2 h1:CG6TE5H9/JXsFWJCfoIVpKFIkFe6ysEuHirp4DxCsHI= -github.com/hashicorp/go-hclog v0.9.2/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-multierror v1.1.1 h1:H5DkEtf6CXdFp0N0Em5UCwQpXMWke8IA0+lD48awMYo= github.com/hashicorp/go-multierror v1.1.1/go.mod h1:iw975J/qwKPdAO1clOe2L8331t/9/fmwbPZ6JB6eMoM= -github.com/hashicorp/go-retryablehttp v0.7.5 h1:bJj+Pj19UZMIweq/iie+1u5YCdGrnxCT9yvm0e+Nd5M= -github.com/hashicorp/go-retryablehttp v0.7.5/go.mod h1:Jy/gPYAdjqffZ/yFGCFV2doI5wjtH1ewM9u8iYVjtX8= github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.2 h1:jzhAVGtqPKbwpyCPELlgNWhE1znq+qwJtW5Oi2viEzc= @@ -38,7 +42,11 @@ github.com/hashicorp/vault-client-go v0.4.3/go.mod h1:4tDw7Uhq5XOxS1fO+oMtotHL7j github.com/hashicorp/vault/api v1.16.0 h1:nbEYGJiAPGzT9U4oWgaaB0g+Rj8E59QuHKyA5LhwQN4= github.com/hashicorp/vault/api v1.16.0/go.mod h1:KhuUhzOD8lDSk29AtzNjgAu2kxRA9jL9NAbkFlqvkBA= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.1.0 h1:lukF9ziXFxDFPkA1vsr5zpc1XuPDn/wFntq5mG+4E0Y= github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= @@ -53,18 +61,14 @@ github.com/ryanuber/columnize v2.1.0+incompatible/go.mod h1:sm1tb6uqfes/u+d4ooFo github.com/ryanuber/go-glob v1.0.0 h1:iQh3xXAumdQ+4Ufa5b25cRpC5TYKlno6hsv6Cb3pkBk= github.com/ryanuber/go-glob v1.0.0/go.mod h1:807d1WSdnB0XRJzKNil9Om6lcp/3a0v4qIHxIXzX/Yc= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= -github.com/stretchr/testify v1.2.2/go.mod h1:a8OnRcib4nhh0OaRAV+Yts87kKdq0PP7pXfy6kDkUVs= github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= -github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= -github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/stretchr/testify v1.8.4 h1:CcVxjf3Q8PM0mHUKJCdn+eZZtm5yQwehR5yeSVQQcUk= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= golang.org/x/crypto v0.32.0 h1:euUpcYgM8WcP71gNpTqQCn6rC2t6ULUPiOzfWaXVVfc= golang.org/x/crypto v0.32.0/go.mod h1:ZnnJkOaASj8g0AjIduWNlq2NRxL0PlBrbKVyZ6V/Ugc= golang.org/x/net v0.34.0 h1:Mb7Mrk043xzHgnRM88suvJFwzVrRfHEHJEl5/71CKw0= golang.org/x/net v0.34.0/go.mod h1:di0qlW3YNM5oh6GqDGQr92MyTozJPmybPK4Ev/Gm31k= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= -golang.org/x/sys v0.19.0 h1:q5f1RH2jigJ1MoAWp2KTp3gm5zAGFUTarQZ5U386+4o= -golang.org/x/sys v0.19.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/sys v0.29.0 h1:TPYlXGxvx1MGTn2GiZDhnjPA9wZzZeGKHHmKhHYvgaU= golang.org/x/sys v0.29.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= diff --git a/go_tests/main.go b/go_tests/main.go new file mode 100644 index 0000000..cf4c56f --- /dev/null +++ b/go_tests/main.go @@ -0,0 +1,26 @@ +package main + +import ( + "log/slog" + // "github.com/openbao/openbao" +) + +// vault cmd args: >vault server -dev -dev-root-token-id="my-token" + +func main() { + slog.Info("run tests in tests/ with >go test") + // // prepare a client with the given base address + // client, err := vault.New( + // vault.WithAddress("http://localhost:8200"), + // vault.WithRequestTimeout(30*time.Second), + // ) + // if err != nil { + // log.Fatal(err) + // } + // log.Println("client prepared") + + // // authenticate with a root token (insecure) + // if err := client.SetToken("my-token"); err != nil { + // log.Fatal(err) + // } +} diff --git a/go_client/tests/secret_test.go b/go_tests/tests/secret_test.go similarity index 94% rename from go_client/tests/secret_test.go rename to go_tests/tests/secret_test.go index a1725dd..9b6de21 100644 --- a/go_client/tests/secret_test.go +++ b/go_tests/tests/secret_test.go @@ -11,15 +11,12 @@ import ( // "github.com/hashicorp/vault-client-go" // "github.com/hashicorp/vault-client-go/schema" vault "github.com/hashicorp/vault/api" + // vault "github.com/openbao/openbao/api/v2" ) var client *vault.Client var ctx context.Context -// Apparently used as a default if mountpath is an empty string (client library) -var mountpath = "/kv-v2" -var mountpath2 = "/some" - func TestMain(m *testing.M) { ctx = context.Background() var err error @@ -82,6 +79,10 @@ func kv2Delete(t *testing.T, mount string, path string) { // https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#create-update-secret // @Philip der Path steht in der KvV2Write Methode func TestWriteSecret(t *testing.T) { + // Apparently used as a default if mountpath is an empty string (client library) + var mountpath = "/kv-v2" + var mountpath2 = "/some" + // Path foo t.Logf("Writing to first KV2 engine at %s...", mountpath) kv2Write(t, mountpath, "foo") diff --git a/migrations/20240501152243_KvSecret.sql b/migrations/20240501152243_KvSecret.sql index 3ce8162..6736fd0 100644 --- a/migrations/20240501152243_KvSecret.sql +++ b/migrations/20240501152243_KvSecret.sql @@ -20,7 +20,7 @@ CREATE TABLE kv2_secret_version ( engine_path TEXT NOT NULL, secret_path TEXT NOT NULL, - version_number INTEGER NOT NULL, + version_number INTEGER NOT NULL CHECK ( version_number > 0 ), secret_data TEXT NOT NULL, created_time DATETIME NOT NULL, deletion_time DATETIME, diff --git a/openapi-bao.json b/openapi-bao.json new file mode 100644 index 0000000..0d38faf --- /dev/null +++ b/openapi-bao.json @@ -0,0 +1,11464 @@ +{ + "openapi": "3.0.2", + "info": { + "title": "OpenBao API", + "description": "HTTP API that gives you full access to OpenBao. All API routes are prefixed with `/v1/`.", + "version": "2.2.0", + "license": { + "name": "Mozilla Public License 2.0", + "url": "https://www.mozilla.org/en-US/MPL/2.0" + } + }, + "paths": { + "/auth/token/accessors": { + "description": "List token accessors, which can then be be used to iterate and discover their properties or revoke them. Because this can be used to cause a denial of service, this endpoint requires 'sudo' capability in addition to 'list'.", + "x-vault-sudo": true, + "get": { + "operationId": "token-list-accessors", + "tags": [ + "auth" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/create": { + "description": "The token create path is used to create new tokens.", + "post": { + "operationId": "token-create", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenCreateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/create-orphan": { + "description": "The token create path is used to create new orphan tokens.", + "post": { + "operationId": "token-create-orphan", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenCreateOrphanRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/create/{role_name}": { + "description": "This token create path is used to create new tokens adhering to the given role.", + "parameters": [ + { + "name": "role_name", + "description": "Name of the role", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "operationId": "token-create-against-role", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenCreateAgainstRoleRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/lookup": { + "description": "This endpoint will lookup a token and its properties.", + "get": { + "operationId": "token-look-up-2", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "token-look-up", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenLookUpRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/lookup-accessor": { + "description": "This endpoint will lookup a token associated with the given accessor and its properties. Response will not contain the token ID.", + "post": { + "operationId": "token-look-up-accessor", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenLookUpAccessorRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/lookup-self": { + "description": "This endpoint will lookup a token and its properties.", + "get": { + "operationId": "token-look-up-self", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "token-look-up-self2", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenLookUpSelf2Request" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/renew": { + "description": "This endpoint will renew the given token and prevent expiration.", + "post": { + "operationId": "token-renew", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRenewRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/renew-accessor": { + "description": "This endpoint will renew a token associated with the given accessor and its properties. Response will not contain the token ID.", + "post": { + "operationId": "token-renew-accessor", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRenewAccessorRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/renew-self": { + "description": "This endpoint will renew the token used to call it and prevent expiration.", + "post": { + "operationId": "token-renew-self", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRenewSelfRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/revoke": { + "description": "This endpoint will delete the given token and all of its child tokens.", + "post": { + "operationId": "token-revoke", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRevokeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/revoke-accessor": { + "description": "This endpoint will delete the token associated with the accessor and all of its child tokens.", + "post": { + "operationId": "token-revoke-accessor", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRevokeAccessorRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/revoke-orphan": { + "description": "This endpoint will delete the token and orphan its child tokens.", + "post": { + "operationId": "token-revoke-orphan", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenRevokeOrphanRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/revoke-self": { + "description": "This endpoint will delete the token used to call it and all of its child tokens.", + "post": { + "operationId": "token-revoke-self", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/roles": { + "description": "This endpoint lists configured roles.", + "get": { + "operationId": "token-list-roles", + "tags": [ + "auth" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/auth/token/roles/{role_name}": { + "parameters": [ + { + "name": "role_name", + "description": "Name of the role", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "token-read-role", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "token-write-role", + "tags": [ + "auth" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/TokenWriteRoleRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "token-delete-role", + "tags": [ + "auth" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/auth/token/tidy": { + "description": "This endpoint performs cleanup tasks that can be run if certain error conditions have occurred.", + "post": { + "operationId": "token-tidy", + "tags": [ + "auth" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/cubbyhole/{path}": { + "description": "Pass-through secret storage to a token-specific cubbyhole in the storage backend, allowing you to read/write arbitrary data into secret storage.", + "parameters": [ + { + "name": "path", + "description": "Specifies the path of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "summary": "Retrieve the secret at the specified location.", + "operationId": "cubbyhole-read", + "tags": [ + "secrets" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Store a secret at the specified location.", + "operationId": "cubbyhole-write", + "tags": [ + "secrets" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Deletes the secret at the specified location.", + "operationId": "cubbyhole-delete", + "tags": [ + "secrets" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/alias": { + "description": "Create a new alias.", + "post": { + "operationId": "alias-create", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AliasCreateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/alias/id": { + "description": "List all the alias IDs.", + "get": { + "operationId": "alias-list-by-id", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/alias/id/{id}": { + "description": "Update, read or delete an alias ID.", + "parameters": [ + { + "name": "id", + "description": "ID of the alias", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "alias-read-by-id", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "alias-update-by-id", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AliasUpdateByIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "alias-delete-by-id", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/entity": { + "description": "Create a new entity", + "post": { + "operationId": "entity-create", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityCreateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity-alias": { + "description": "Create a new alias.", + "post": { + "operationId": "entity-create-alias", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityCreateAliasRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity-alias/id": { + "description": "List all the alias IDs.", + "get": { + "operationId": "entity-list-aliases-by-id", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity-alias/id/{id}": { + "description": "Update, read or delete an alias ID.", + "parameters": [ + { + "name": "id", + "description": "ID of the alias", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "entity-read-alias-by-id", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "entity-update-alias-by-id", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityUpdateAliasByIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "entity-delete-alias-by-id", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/entity/batch-delete": { + "description": "Delete all of the entities provided", + "post": { + "operationId": "entity-batch-delete", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityBatchDeleteRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity/id": { + "description": "List all the entity IDs", + "get": { + "operationId": "entity-list-by-id", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity/id/{id}": { + "description": "Update, read or delete an entity using entity ID", + "parameters": [ + { + "name": "id", + "description": "ID of the entity. If set, updates the corresponding existing entity.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "entity-read-by-id", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "entity-update-by-id", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityUpdateByIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "entity-delete-by-id", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/entity/merge": { + "description": "Merge two or more entities together", + "post": { + "operationId": "entity-merge", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityMergeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity/name": { + "description": "List all the entity names", + "get": { + "operationId": "entity-list-by-name", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/entity/name/{name}": { + "description": "Update, read or delete an entity using entity name", + "parameters": [ + { + "name": "name", + "description": "Name of the entity", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "entity-read-by-name", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "entity-update-by-name", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityUpdateByNameRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "entity-delete-by-name", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/group": { + "description": "Create a new group.", + "post": { + "operationId": "group-create", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupCreateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/group-alias": { + "description": "Creates a new group alias, or updates an existing one.", + "post": { + "operationId": "group-create-alias", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupCreateAliasRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/group-alias/id": { + "description": "List all the group alias IDs.", + "get": { + "operationId": "group-list-aliases-by-id", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/group-alias/id/{id}": { + "parameters": [ + { + "name": "id", + "description": "ID of the group alias.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "group-read-alias-by-id", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "group-update-alias-by-id", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupUpdateAliasByIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "group-delete-alias-by-id", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/group/id": { + "description": "List all the group IDs.", + "get": { + "operationId": "group-list-by-id", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/group/id/{id}": { + "description": "Update or delete an existing group using its ID.", + "parameters": [ + { + "name": "id", + "description": "ID of the group. If set, updates the corresponding existing group.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "group-read-by-id", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "group-update-by-id", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupUpdateByIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "group-delete-by-id", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/group/name": { + "get": { + "operationId": "group-list-by-name", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/group/name/{name}": { + "parameters": [ + { + "name": "name", + "description": "Name of the group.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "group-read-by-name", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "group-update-by-name", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupUpdateByNameRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "group-delete-by-name", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/lookup/entity": { + "description": "Query entities based on various properties.", + "post": { + "operationId": "entity-look-up", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EntityLookUpRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/lookup/group": { + "description": "Query groups based on various properties.", + "post": { + "operationId": "group-look-up", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GroupLookUpRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/login-enforcement": { + "get": { + "summary": "List login enforcements", + "operationId": "mfa-list-login-enforcements", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/login-enforcement/{name}": { + "parameters": [ + { + "name": "name", + "description": "Name for this login enforcement configuration", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the current login enforcement", + "operationId": "mfa-read-login-enforcement", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Create or update a login enforcement", + "operationId": "mfa-write-login-enforcement", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaWriteLoginEnforcementRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete a login enforcement", + "operationId": "mfa-delete-login-enforcement", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/mfa/method": { + "get": { + "summary": "List MFA method configurations for all MFA methods", + "operationId": "mfa-list-methods", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/duo": { + "get": { + "summary": "List MFA method configurations for the given MFA method", + "operationId": "mfa-list-duo-methods", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/duo/{method_id}": { + "parameters": [ + { + "name": "method_id", + "description": "The unique identifier for this MFA method.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the current configuration for the given MFA method", + "operationId": "mfa-read-duo-method-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Update or create a configuration for the given MFA method", + "operationId": "mfa-configure-duo-method", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaConfigureDuoMethodRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete a configuration for the given MFA method", + "operationId": "mfa-delete-duo-method", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/mfa/method/okta": { + "get": { + "summary": "List MFA method configurations for the given MFA method", + "operationId": "mfa-list-okta-methods", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/okta/{method_id}": { + "parameters": [ + { + "name": "method_id", + "description": "The unique identifier for this MFA method.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the current configuration for the given MFA method", + "operationId": "mfa-read-okta-method-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Update or create a configuration for the given MFA method", + "operationId": "mfa-configure-okta-method", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaConfigureOktaMethodRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete a configuration for the given MFA method", + "operationId": "mfa-delete-okta-method", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/mfa/method/pingid": { + "get": { + "summary": "List MFA method configurations for the given MFA method", + "operationId": "mfa-list-ping-id-methods", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/pingid/{method_id}": { + "parameters": [ + { + "name": "method_id", + "description": "The unique identifier for this MFA method.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the current configuration for the given MFA method", + "operationId": "mfa-read-ping-id-method-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Update or create a configuration for the given MFA method", + "operationId": "mfa-configure-ping-id-method", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaConfigurePingIdMethodRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete a configuration for the given MFA method", + "operationId": "mfa-delete-ping-id-method", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/mfa/method/totp": { + "get": { + "summary": "List MFA method configurations for the given MFA method", + "operationId": "mfa-list-totp-methods", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/totp/admin-destroy": { + "post": { + "summary": "Destroys a TOTP secret for the given MFA method ID on the given entity", + "operationId": "mfa-admin-destroy-totp-secret", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaAdminDestroyTotpSecretRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/totp/admin-generate": { + "post": { + "summary": "Update or create TOTP secret for the given method ID on the given entity.", + "operationId": "mfa-admin-generate-totp-secret", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaAdminGenerateTotpSecretRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/totp/generate": { + "post": { + "summary": "Update or create TOTP secret for the given method ID on the given entity.", + "operationId": "mfa-generate-totp-secret", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaGenerateTotpSecretRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/mfa/method/totp/{method_id}": { + "parameters": [ + { + "name": "method_id", + "description": "The unique identifier for this MFA method.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the current configuration for the given MFA method", + "operationId": "mfa-read-totp-method-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Update or create a configuration for the given MFA method", + "operationId": "mfa-configure-totp-method", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaConfigureTotpMethodRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete a configuration for the given MFA method", + "operationId": "mfa-delete-totp-method", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/mfa/method/{method_id}": { + "parameters": [ + { + "name": "method_id", + "description": "The unique identifier for this MFA method.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the current configuration for the given ID regardless of the MFA method type", + "operationId": "mfa-read-method-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/.well-known/keys": { + "description": "Retrieve public keys", + "x-vault-unauthenticated": true, + "get": { + "operationId": "oidc-read-public-keys", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/.well-known/openid-configuration": { + "description": "Query OIDC configurations", + "x-vault-unauthenticated": true, + "get": { + "operationId": "oidc-read-open-id-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/assignment": { + "description": "List OIDC assignments", + "get": { + "operationId": "oidc-list-assignments", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/assignment/{name}": { + "description": "CRUD operations for OIDC assignments.", + "parameters": [ + { + "name": "name", + "description": "Name of the assignment", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "oidc-read-assignment", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-write-assignment", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcWriteAssignmentRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "oidc-delete-assignment", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/oidc/client": { + "description": "List OIDC clients", + "get": { + "operationId": "oidc-list-clients", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/client/{name}": { + "description": "CRUD operations for OIDC clients.", + "parameters": [ + { + "name": "name", + "description": "Name of the client.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "oidc-read-client", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-write-client", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcWriteClientRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "oidc-delete-client", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/oidc/config": { + "description": "OIDC configuration", + "get": { + "operationId": "oidc-read-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-configure", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcConfigureRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/introspect": { + "description": "Verify the authenticity of an OIDC token", + "post": { + "operationId": "oidc-introspect", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcIntrospectRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/key": { + "description": "List OIDC keys", + "get": { + "operationId": "oidc-list-keys", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/key/{name}": { + "description": "CRUD operations for OIDC keys.", + "parameters": [ + { + "name": "name", + "description": "Name of the key", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "oidc-read-key", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-write-key", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcWriteKeyRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "oidc-delete-key", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/oidc/key/{name}/rotate": { + "description": "Rotate a named OIDC key.", + "parameters": [ + { + "name": "name", + "description": "Name of the key", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "operationId": "oidc-rotate-key", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcRotateKeyRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/provider": { + "description": "List OIDC providers", + "parameters": [ + { + "name": "allowed_client_id", + "description": "Filters the list of OIDC providers to those that allow the given client ID in their set of allowed_client_ids.", + "in": "query", + "schema": { + "type": "string", + "default": "" + } + } + ], + "get": { + "operationId": "oidc-list-providers", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/provider/{name}": { + "description": "CRUD operations for OIDC providers.", + "parameters": [ + { + "name": "name", + "description": "Name of the provider", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "oidc-read-provider", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-write-provider", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcWriteProviderRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "oidc-delete-provider", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/oidc/provider/{name}/.well-known/keys": { + "description": "Retrieve public keys", + "parameters": [ + { + "name": "name", + "description": "Name of the provider", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-unauthenticated": true, + "get": { + "operationId": "oidc-read-provider-public-keys", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/provider/{name}/.well-known/openid-configuration": { + "description": "Query OIDC configurations", + "parameters": [ + { + "name": "name", + "description": "Name of the provider", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-unauthenticated": true, + "get": { + "operationId": "oidc-read-provider-open-id-configuration", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/provider/{name}/authorize": { + "description": "Provides the OIDC Authorization Endpoint.", + "parameters": [ + { + "name": "name", + "description": "Name of the provider", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "oidc-provider-authorize", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-provider-authorize-with-parameters", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcProviderAuthorizeWithParametersRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/provider/{name}/token": { + "description": "Provides the OIDC Token Endpoint.", + "parameters": [ + { + "name": "name", + "description": "Name of the provider", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-unauthenticated": true, + "post": { + "operationId": "oidc-provider-token", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcProviderTokenRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/provider/{name}/userinfo": { + "description": "Provides the OIDC UserInfo Endpoint.", + "parameters": [ + { + "name": "name", + "description": "Name of the provider", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "oidc-provider-user-info", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-provider-user-info2", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/role": { + "description": "List configured OIDC roles", + "get": { + "operationId": "oidc-list-roles", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/role/{name}": { + "description": "CRUD operations on OIDC Roles", + "parameters": [ + { + "name": "name", + "description": "Name of the role", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "oidc-read-role", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-write-role", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcWriteRoleRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "oidc-delete-role", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/oidc/scope": { + "description": "List OIDC scopes", + "get": { + "operationId": "oidc-list-scopes", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/oidc/scope/{name}": { + "description": "CRUD operations for OIDC scopes.", + "parameters": [ + { + "name": "name", + "description": "Name of the scope", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "oidc-read-scope", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "oidc-write-scope", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/OidcWriteScopeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "oidc-delete-scope", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/identity/oidc/token/{name}": { + "description": "Generate an OIDC token", + "parameters": [ + { + "name": "name", + "description": "Name of the role", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "oidc-generate-token", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/persona": { + "description": "Create a new alias.", + "post": { + "operationId": "persona-create", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaCreateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/persona/id": { + "description": "List all the alias IDs.", + "get": { + "operationId": "persona-list-by-id", + "tags": [ + "identity" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/identity/persona/id/{id}": { + "description": "Update, read or delete an alias ID.", + "parameters": [ + { + "name": "id", + "description": "ID of the persona", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "persona-read-by-id", + "tags": [ + "identity" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "persona-update-by-id", + "tags": [ + "identity" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PersonaUpdateByIdRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "persona-delete-by-id", + "tags": [ + "identity" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/sys/audit": { + "description": "List the currently enabled audit backends.", + "x-vault-sudo": true, + "get": { + "summary": "List the enabled audit devices.", + "operationId": "auditing-list-enabled-devices", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/audit-hash/{path}": { + "description": "The hash of the given string via the given audit backend", + "parameters": [ + { + "name": "path", + "description": "The name of the backend. Cannot be delimited. Example: \"mysql\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "operationId": "auditing-calculate-hash", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditingCalculateHashRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditingCalculateHashResponse" + } + } + } + } + } + } + }, + "/sys/audit/{path}": { + "description": "Enable or disable audit backends.", + "parameters": [ + { + "name": "path", + "description": "The name of the backend. Cannot be delimited. Example: \"mysql\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "post": { + "summary": "Enable a new audit device at the supplied path.", + "operationId": "auditing-enable-device", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditingEnableDeviceRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Disable the audit device at the given path.", + "operationId": "auditing-disable-device", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/auth": { + "description": "List the currently enabled credential backends.", + "get": { + "operationId": "auth-list-enabled-methods", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/auth/{path}": { + "description": "Enable a new credential backend with a name.", + "parameters": [ + { + "name": "path", + "description": "The path to mount to. Cannot be delimited. Example: \"user\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "Read the configuration of the auth engine at the given path.", + "operationId": "auth-read-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthReadConfigurationResponse" + } + } + } + } + } + }, + "post": { + "summary": "Enables a new auth method.", + "description": "After enabling, the auth method can be accessed and configured via the auth path specified as part of the URL. This auth path will be nested under the auth prefix.\n\nFor example, enable the \"foo\" auth method will make it accessible at /auth/foo.", + "operationId": "auth-enable-method", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthEnableMethodRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Disable the auth method at the given auth path", + "operationId": "auth-disable-method", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/auth/{path}/tune": { + "description": "Tune the configuration parameters for an auth path.", + "parameters": [ + { + "name": "path", + "description": "Tune the configuration parameters for an auth path.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "Reads the given auth path's configuration.", + "description": "This endpoint requires sudo capability on the final path, but the same functionality can be achieved without sudo via `sys/mounts/auth/[auth-path]/tune`.", + "operationId": "auth-read-tuning-information", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthReadTuningInformationResponse" + } + } + } + } + } + }, + "post": { + "summary": "Tune configuration parameters for a given auth path.", + "description": "This endpoint requires sudo capability on the final path, but the same functionality can be achieved without sudo via `sys/mounts/auth/[auth-path]/tune`.", + "operationId": "auth-tune-configuration-parameters", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuthTuneConfigurationParametersRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/capabilities": { + "description": "Fetches the capabilities of the given token on the given path.", + "post": { + "operationId": "query-token-capabilities", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryTokenCapabilitiesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/capabilities-accessor": { + "description": "Fetches the capabilities of the token associated with the given token, on the given path.", + "post": { + "operationId": "query-token-accessor-capabilities", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryTokenAccessorCapabilitiesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/capabilities-self": { + "description": "Fetches the capabilities of the given token on the given path.", + "post": { + "operationId": "query-token-self-capabilities", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/QueryTokenSelfCapabilitiesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/config/auditing/request-headers": { + "description": "Lists the headers configured to be audited.", + "x-vault-sudo": true, + "get": { + "summary": "List the request headers that are configured to be audited.", + "operationId": "auditing-list-request-headers", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditingListRequestHeadersResponse" + } + } + } + } + } + } + }, + "/sys/config/auditing/request-headers/{header}": { + "description": "Configures the headers sent to the audit logs.", + "parameters": [ + { + "name": "header", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "List the information for the given request header.", + "operationId": "auditing-read-request-header-information", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Enable auditing of a header.", + "operationId": "auditing-enable-request-header", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/AuditingEnableRequestHeaderRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Disable auditing of the given request header.", + "operationId": "auditing-disable-request-header", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/config/cors": { + "description": "This path responds to the following HTTP methods. GET / Returns the configuration of the CORS setting. POST / Sets the comma-separated list of origins that can make cross-origin requests. DELETE / Clears the CORS configuration and disables acceptance of CORS requests.", + "x-vault-sudo": true, + "get": { + "summary": "Return the current CORS settings.", + "operationId": "cors-read-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CorsReadConfigurationResponse" + } + } + } + } + } + }, + "post": { + "summary": "Configure the CORS settings.", + "operationId": "cors-configure", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CorsConfigureRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Remove any CORS settings.", + "operationId": "cors-delete-configuration", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/config/reload/{subsystem}": { + "parameters": [ + { + "name": "subsystem", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "summary": "Reload the given subsystem", + "operationId": "reload-subsystem", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/config/state/sanitized": { + "get": { + "summary": "Return a sanitized version of the OpenBao server configuration.", + "description": "The sanitized output strips configuration values in the storage, HA storage, and seals stanzas, which may contain sensitive values such as API tokens. It also removes any token or secret fields in other stanzas, such as the circonus_api_token from telemetry.", + "operationId": "read-sanitized-configuration-state", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/config/ui/headers": { + "description": "This path responds to the following HTTP methods. GET /\u003cheader\u003e Returns the header value. POST /\u003cheader\u003e Sets the header value for the UI. DELETE /\u003cheader\u003e Clears the header value for UI. LIST / List the headers configured for the UI.", + "get": { + "summary": "Return a list of configured UI headers.", + "operationId": "ui-headers-list", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UiHeadersListResponse" + } + } + } + } + } + } + }, + "/sys/config/ui/headers/{header}": { + "description": "This path responds to the following HTTP methods. GET /\u003cheader\u003e Returns the header value. POST /\u003cheader\u003e Sets the header value for the UI. DELETE /\u003cheader\u003e Clears the header value for UI. LIST / List the headers configured for the UI.", + "parameters": [ + { + "name": "header", + "description": "The name of the header.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "Return the given UI header's configuration", + "operationId": "ui-headers-read-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UiHeadersReadConfigurationResponse" + } + } + } + } + } + }, + "post": { + "summary": "Configure the values to be returned for the UI header.", + "operationId": "ui-headers-configure", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UiHeadersConfigureRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Remove a UI header.", + "operationId": "ui-headers-delete-configuration", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/decode-token": { + "x-vault-unauthenticated": true, + "post": { + "summary": "Decodes the encoded token with the otp.", + "operationId": "decode", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/DecodeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/generate-root": { + "description": "Reads, generates, or deletes a root token regeneration process.", + "get": { + "summary": "Read the configuration and progress of the current root generation attempt.", + "operationId": "root-token-generation-read-progress2", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationReadProgress2Response" + } + } + } + } + } + }, + "post": { + "summary": "Initializes a new root generation attempt.", + "description": "Only a single root generation attempt can take place at a time. One (and only one) of otp or pgp_key are required.", + "operationId": "root-token-generation-initialize-2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationInitialize2Request" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationInitialize2Response" + } + } + } + } + } + }, + "delete": { + "summary": "Cancels any in-progress root generation attempt.", + "operationId": "root-token-generation-cancel-2", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/generate-root/attempt": { + "description": "Reads, generates, or deletes a root token regeneration process.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Read the configuration and progress of the current root generation attempt.", + "operationId": "root-token-generation-read-progress", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationReadProgressResponse" + } + } + } + } + } + }, + "post": { + "summary": "Initializes a new root generation attempt.", + "description": "Only a single root generation attempt can take place at a time. One (and only one) of otp or pgp_key are required.", + "operationId": "root-token-generation-initialize", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationInitializeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationInitializeResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Cancels any in-progress root generation attempt.", + "operationId": "root-token-generation-cancel", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/generate-root/update": { + "description": "Reads, generates, or deletes a root token regeneration process.", + "x-vault-unauthenticated": true, + "post": { + "summary": "Enter a single unseal key share to progress the root generation attempt.", + "description": "If the threshold number of unseal key shares is reached, OpenBao will complete the root generation and issue the new token. Otherwise, this API must be called multiple times until that threshold is met. The attempt nonce must be provided with each call.", + "operationId": "root-token-generation-update", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RootTokenGenerationUpdateResponse" + } + } + } + } + } + } + }, + "/sys/ha-status": { + "description": "Provides information about the nodes in an HA cluster.", + "get": { + "summary": "Check the HA status of an OpenBao cluster", + "operationId": "ha-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/HaStatusResponse" + } + } + } + } + } + } + }, + "/sys/health": { + "description": "Checks the health status of OpenBao.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Returns the health status of OpenBao.", + "operationId": "read-health-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "initialized, unsealed, and active" + }, + "429": { + "description": "unsealed and standby" + }, + "472": { + "description": "data recovery mode replication secondary and active" + }, + "501": { + "description": "not initialized" + }, + "503": { + "description": "sealed" + } + } + } + }, + "/sys/host-info": { + "description": "Information about the host instance that this OpenBao server is running on.", + "get": { + "summary": "Information about the host instance that this OpenBao server is running on.", + "description": "Information about the host instance that this OpenBao server is running on.\n\t\tThe information that gets collected includes host hardware information, and CPU,\n\t\tdisk, and memory utilization", + "operationId": "collect-host-information", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/CollectHostInformationResponse" + } + } + } + } + } + } + }, + "/sys/in-flight-req": { + "get": { + "summary": "reports in-flight requests", + "description": "This path responds to the following HTTP methods.\n\t\tGET /\n\t\t\tReturns a map of in-flight requests.", + "operationId": "collect-in-flight-request-information", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/init": { + "description": "Initializes or returns the initialization status of OpenBao.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Returns the initialization status of OpenBao.", + "operationId": "read-initialization-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Initialize a new OpenBao instance.", + "description": "The OpenBao instance must not have been previously initialized. The recovery options, as well as the stored shares option, are only available when using OpenBao HSM.", + "operationId": "initialize-system", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InitializeSystemRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/internal/counters/entities": { + "description": "Count of active entities in this OpenBao cluster.", + "get": { + "summary": "Backwards compatibility is not guaranteed for this API", + "operationId": "internal-count-entities", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalCountEntitiesResponse" + } + } + } + } + } + } + }, + "/sys/internal/counters/requests": { + "description": "Currently unsupported. Previously, count of requests seen by this OpenBao cluster over time.", + "get": { + "summary": "Backwards compatibility is not guaranteed for this API", + "operationId": "internal-count-requests", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + }, + "deprecated": true + } + }, + "/sys/internal/counters/tokens": { + "description": "Count of active tokens in this OpenBao cluster.", + "get": { + "summary": "Backwards compatibility is not guaranteed for this API", + "operationId": "internal-count-tokens", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalCountTokensResponse" + } + } + } + } + } + } + }, + "/sys/internal/inspect/request": { + "description": "Outputs information contained within a request to a plugin.", + "x-vault-sudo": true, + "get": { + "summary": "Expose all request information to the caller", + "operationId": "internal-inspect-request", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/internal/inspect/router/{tag}": { + "description": "Information on the entries in each of the trees in the router. Inspectable trees are uuid, accessor, storage, and root.", + "parameters": [ + { + "name": "tag", + "description": "Name of subtree being observed", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "Expose the route entry and mount entry tables present in the router", + "operationId": "internal-inspect-router", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/internal/specs/openapi": { + "description": "Generate an OpenAPI 3 document of all mounted paths.", + "parameters": [ + { + "name": "generic_mount_paths", + "description": "Use generic mount paths", + "in": "query", + "schema": { + "type": "boolean", + "default": false + } + } + ], + "x-vault-unauthenticated": true, + "get": { + "operationId": "internal-generate-open-api-document", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "internal-generate-open-api-document-with-parameters", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalGenerateOpenApiDocumentWithParametersRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/internal/ui/feature-flags": { + "description": "Enabled feature flags. Internal API; its location, inputs, and outputs may change.", + "get": { + "summary": "Lists enabled feature flags.", + "operationId": "internal-ui-list-enabled-feature-flags", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalUiListEnabledFeatureFlagsResponse" + } + } + } + } + } + } + }, + "/sys/internal/ui/mounts": { + "description": "Information about mounts returned according to their tuned visibility. Internal API; its location, inputs, and outputs may change.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Lists all enabled and visible auth and secrets mounts.", + "operationId": "internal-ui-list-enabled-visible-mounts", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalUiListEnabledVisibleMountsResponse" + } + } + } + } + } + } + }, + "/sys/internal/ui/mounts/{path}": { + "description": "Information about mounts returned according to their tuned visibility. Internal API; its location, inputs, and outputs may change.", + "parameters": [ + { + "name": "path", + "description": "The path of the mount.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-unauthenticated": true, + "get": { + "summary": "Return information about the given mount.", + "operationId": "internal-ui-read-mount-information", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalUiReadMountInformationResponse" + } + } + } + } + } + } + }, + "/sys/internal/ui/namespaces": { + "description": "Information about visible child namespaces. Internal API; its location, inputs, and outputs may change.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Backwards compatibility is not guaranteed for this API", + "operationId": "internal-ui-list-namespaces", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalUiListNamespacesResponse" + } + } + } + } + } + } + }, + "/sys/internal/ui/resultant-acl": { + "description": "Information about a token's resultant ACL. Internal API; its location, inputs, and outputs may change.", + "get": { + "summary": "Backwards compatibility is not guaranteed for this API", + "operationId": "internal-ui-read-resultant-acl", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/InternalUiReadResultantAclResponse" + } + } + } + }, + "204": { + "description": "empty response returned if no client token" + } + } + } + }, + "/sys/key-status": { + "description": "Provides information about the backend encryption key.", + "get": { + "operationId": "encryption-key-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/leader": { + "description": "Check the high availability status and current leader of OpenBao", + "x-vault-unauthenticated": true, + "get": { + "summary": "Returns the high availability status and current leader instance of OpenBao.", + "operationId": "leader-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeaderStatusResponse" + } + } + } + } + } + } + }, + "/sys/leases": { + "description": "List leases associated with this OpenBao cluster", + "x-vault-sudo": true, + "get": { + "operationId": "leases-list", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesListResponse" + } + } + } + } + } + } + }, + "/sys/leases/count": { + "description": "Count of leases associated with this OpenBao cluster", + "get": { + "operationId": "leases-count", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesCountResponse" + } + } + } + } + } + } + }, + "/sys/leases/lookup": { + "description": "View or list lease metadata.", + "post": { + "operationId": "leases-read-lease", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesReadLeaseRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesReadLeaseResponse" + } + } + } + } + } + } + }, + "/sys/leases/lookup/": { + "description": "View or list lease metadata.", + "x-vault-sudo": true, + "get": { + "operationId": "leases-look-up", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesLookUpResponse" + } + } + } + } + } + } + }, + "/sys/leases/lookup/{prefix}": { + "description": "View or list lease metadata.", + "parameters": [ + { + "name": "prefix", + "description": "The path to list leases under. Example: \"aws/creds/deploy\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "operationId": "leases-look-up-with-prefix", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesLookUpWithPrefixResponse" + } + } + } + } + } + } + }, + "/sys/leases/renew": { + "description": "Renew a lease on a secret", + "post": { + "summary": "Renews a lease, requesting to extend the lease.", + "operationId": "leases-renew-lease", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRenewLeaseRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/leases/renew/{url_lease_id}": { + "description": "Renew a lease on a secret", + "parameters": [ + { + "name": "url_lease_id", + "description": "The lease identifier to renew. This is included with a lease.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "summary": "Renews a lease, requesting to extend the lease.", + "operationId": "leases-renew-lease-with-id", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRenewLeaseWithIdRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/leases/revoke": { + "description": "Revoke a leased secret immediately", + "post": { + "summary": "Revokes a lease immediately.", + "operationId": "leases-revoke-lease", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRevokeLeaseRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/leases/revoke-force/{prefix}": { + "description": "Revoke all secrets generated in a given prefix, ignoring errors.", + "parameters": [ + { + "name": "prefix", + "description": "The path to revoke keys under. Example: \"prod/aws/ops\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "post": { + "summary": "Revokes all secrets or tokens generated under a given prefix immediately", + "description": "Unlike `/sys/leases/revoke-prefix`, this path ignores backend errors encountered during revocation. This is potentially very dangerous and should only be used in specific emergency situations where errors in the backend or the connected backend service prevent normal revocation.\n\nBy ignoring these errors, OpenBao abdicates responsibility for ensuring that the issued credentials or secrets are properly revoked and/or cleaned up. Access to this endpoint should be tightly controlled.", + "operationId": "leases-force-revoke-lease-with-prefix", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/leases/revoke-prefix/{prefix}": { + "description": "Revoke all secrets generated in a given prefix", + "parameters": [ + { + "name": "prefix", + "description": "The path to revoke keys under. Example: \"prod/aws/ops\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "post": { + "summary": "Revokes all secrets (via a lease ID prefix) or tokens (via the tokens' path property) generated under a given prefix immediately.", + "operationId": "leases-revoke-lease-with-prefix", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRevokeLeaseWithPrefixRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/leases/revoke/{url_lease_id}": { + "description": "Revoke a leased secret immediately", + "parameters": [ + { + "name": "url_lease_id", + "description": "The lease identifier to renew. This is included with a lease.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "summary": "Revokes a lease immediately.", + "operationId": "leases-revoke-lease-with-id", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRevokeLeaseWithIdRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/leases/tidy": { + "description": "This endpoint performs cleanup tasks that can be run if certain error conditions have occurred.", + "post": { + "operationId": "leases-tidy", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/locked-users": { + "description": "Report the locked user count metrics", + "get": { + "summary": "Report the locked user count metrics, for this namespace and all child namespaces.", + "operationId": "locked-users-list", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/locked-users/{mount_accessor}/unlock/{alias_identifier}": { + "description": "Unlock the locked user with given mount_accessor and alias_identifier.", + "parameters": [ + { + "name": "alias_identifier", + "description": "It is the name of the alias (user). For example, if the alias belongs to userpass backend, the name should be a valid username within userpass auth method. If the alias belongs to an approle auth method, the name should be a valid RoleID", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "mount_accessor", + "description": "MountAccessor is the identifier of the mount entry to which the user belongs", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "summary": "Unlocks the user with given mount_accessor and alias_identifier", + "operationId": "locked-users-unlock", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/loggers": { + "get": { + "summary": "Read the log level for all existing loggers.", + "operationId": "loggers-read-verbosity-level", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Modify the log level for all existing loggers.", + "operationId": "loggers-update-verbosity-level", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggersUpdateVerbosityLevelRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Revert the all loggers to use log level provided in config.", + "operationId": "loggers-revert-verbosity-level", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/loggers/{name}": { + "parameters": [ + { + "name": "name", + "description": "The name of the logger to be modified.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the log level for a single logger.", + "operationId": "loggers-read-verbosity-level-for", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Modify the log level of a single logger.", + "operationId": "loggers-update-verbosity-level-for", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LoggersUpdateVerbosityLevelForRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Revert a single logger to use log level provided in config.", + "operationId": "loggers-revert-verbosity-level-for", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/metrics": { + "description": "Export the metrics aggregated for telemetry purpose.", + "parameters": [ + { + "name": "format", + "description": "Format to export metrics into. Currently accepts only \"prometheus\".", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "get": { + "operationId": "metrics", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/mfa/validate": { + "x-vault-unauthenticated": true, + "post": { + "summary": "Validates the login for the given MFA methods. Upon successful validation, it returns an auth response containing the client token", + "operationId": "mfa-validate", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MfaValidateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/monitor": { + "parameters": [ + { + "name": "log_format", + "description": "Output format of logs. Supported values are \"standard\" and \"json\". The default is \"standard\".", + "in": "query", + "schema": { + "type": "string", + "default": "standard" + } + }, + { + "name": "log_level", + "description": "Log level to view system logs at. Currently supported values are \"trace\", \"debug\", \"info\", \"warn\", \"error\".", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "get": { + "operationId": "monitor", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/mounts": { + "description": "List the currently mounted backends.", + "get": { + "operationId": "mounts-list-secrets-engines", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/mounts/{path}": { + "description": "Mount a new backend at a new path.", + "parameters": [ + { + "name": "path", + "description": "The path to mount to. Example: \"aws/east\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Read the configuration of the secret engine at the given path.", + "operationId": "mounts-read-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MountsReadConfigurationResponse" + } + } + } + } + } + }, + "post": { + "summary": "Enable a new secrets engine at the given path.", + "operationId": "mounts-enable-secrets-engine", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MountsEnableSecretsEngineRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Disable the mount point specified at the given path.", + "operationId": "mounts-disable-secrets-engine", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/mounts/{path}/tune": { + "description": "Tune backend configuration parameters for this mount.", + "parameters": [ + { + "name": "path", + "description": "The path to mount to. Example: \"aws/east\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "mounts-read-tuning-information", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MountsReadTuningInformationResponse" + } + } + } + } + } + }, + "post": { + "operationId": "mounts-tune-configuration-parameters", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/MountsTuneConfigurationParametersRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/plugins/catalog": { + "description": "Lists all the plugins known to OpenBao", + "get": { + "operationId": "plugins-catalog-list-plugins", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsCatalogListPluginsResponse" + } + } + } + } + } + } + }, + "/sys/plugins/catalog/{name}": { + "description": "Configures the plugins known to OpenBao", + "parameters": [ + { + "name": "name", + "description": "The name of the plugin", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "Return the configuration data for the plugin with the given name.", + "operationId": "plugins-catalog-read-plugin-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsCatalogReadPluginConfigurationResponse" + } + } + } + } + } + }, + "post": { + "summary": "Register a new plugin, or updates an existing one with the supplied name.", + "operationId": "plugins-catalog-register-plugin", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsCatalogRegisterPluginRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Remove the plugin with the given name.", + "operationId": "plugins-catalog-remove-plugin", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/plugins/catalog/{type}": { + "description": "Configures the plugins known to OpenBao", + "parameters": [ + { + "name": "type", + "description": "The type of the plugin, may be auth, secret, or database", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "List the plugins in the catalog.", + "operationId": "plugins-catalog-list-plugins-with-type", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsCatalogListPluginsWithTypeResponse" + } + } + } + } + } + } + }, + "/sys/plugins/catalog/{type}/{name}": { + "description": "Configures the plugins known to OpenBao", + "parameters": [ + { + "name": "name", + "description": "The name of the plugin", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "type", + "description": "The type of the plugin, may be auth, secret, or database", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "get": { + "summary": "Return the configuration data for the plugin with the given name.", + "operationId": "plugins-catalog-read-plugin-configuration-with-type", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsCatalogReadPluginConfigurationWithTypeResponse" + } + } + } + } + } + }, + "post": { + "summary": "Register a new plugin, or updates an existing one with the supplied name.", + "operationId": "plugins-catalog-register-plugin-with-type", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsCatalogRegisterPluginWithTypeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Remove the plugin with the given name.", + "operationId": "plugins-catalog-remove-plugin-with-type", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/plugins/reload/backend": { + "description": "Reload mounts that use a particular backend plugin.", + "post": { + "summary": "Reload mounted plugin backends.", + "description": "Either the plugin name (`plugin`) or the desired plugin backend mounts (`mounts`) must be provided, but not both. In the case that the plugin name is provided, all mounted paths that use that plugin backend will be reloaded. If (`scope`) is provided and is (`global`), the plugin(s) are reloaded globally.", + "operationId": "plugins-reload-backends", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsReloadBackendsRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsReloadBackendsResponse" + } + } + } + }, + "202": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PluginsReloadBackendsResponse" + } + } + } + } + } + } + }, + "/sys/policies/acl": { + "description": "List the configured access control policies.", + "get": { + "operationId": "policies-list-acl-policies", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesListAclPoliciesResponse" + } + } + } + } + } + } + }, + "/sys/policies/acl/{name}": { + "description": "Read, Modify, or Delete an access control policy.", + "parameters": [ + { + "name": "name", + "description": "The name of the policy. Example: \"ops\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Retrieve information about the named ACL policy.", + "operationId": "policies-read-acl-policy", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesReadAclPolicyResponse" + } + } + } + } + } + }, + "post": { + "summary": "Add a new or update an existing ACL policy.", + "operationId": "policies-write-acl-policy", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesWriteAclPolicyRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete the ACL policy with the given name.", + "operationId": "policies-delete-acl-policy", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/policies/password": { + "get": { + "summary": "List the existing password policies.", + "operationId": "policies-list-password-policies", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesListPasswordPoliciesResponse" + } + } + } + } + } + } + }, + "/sys/policies/password/{name}": { + "description": "Read, Modify, or Delete a password policy.", + "parameters": [ + { + "name": "name", + "description": "The name of the password policy.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Retrieve an existing password policy.", + "operationId": "policies-read-password-policy", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesReadPasswordPolicyResponse" + } + } + } + } + } + }, + "post": { + "summary": "Add a new or update an existing password policy.", + "operationId": "policies-write-password-policy", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesWritePasswordPolicyRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete a password policy.", + "operationId": "policies-delete-password-policy", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/policies/password/{name}/generate": { + "description": "Generate a password from an existing password policy.", + "parameters": [ + { + "name": "name", + "description": "The name of the password policy.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Generate a password from an existing password policy.", + "operationId": "policies-generate-password-from-password-policy", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesGeneratePasswordFromPasswordPolicyResponse" + } + } + } + } + } + } + }, + "/sys/policy": { + "description": "List the configured access control policies.", + "get": { + "operationId": "policies-list", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesListResponse" + } + } + } + } + } + } + }, + "/sys/policy/{name}": { + "description": "Read, Modify, or Delete an access control policy.", + "parameters": [ + { + "name": "name", + "description": "The name of the policy. Example: \"ops\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Retrieve the policy body for the named policy.", + "operationId": "policies-read-acl-policy2", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesReadAclPolicy2Response" + } + } + } + } + } + }, + "post": { + "summary": "Add a new or update an existing policy.", + "operationId": "policies-write-acl-policy2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/PoliciesWriteAclPolicy2Request" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete the policy with the given name.", + "operationId": "policies-delete-acl-policy2", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/pprof": { + "get": { + "summary": "Returns an HTML page listing the available profiles.", + "description": "Returns an HTML page listing the available \nprofiles. This should be mainly accessed via browsers or applications that can \nrender pages.", + "operationId": "pprof-index", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/allocs": { + "get": { + "summary": "Returns a sampling of all past memory allocations.", + "description": "Returns a sampling of all past memory allocations.", + "operationId": "pprof-memory-allocations", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/block": { + "get": { + "summary": "Returns stack traces that led to blocking on synchronization primitives", + "description": "Returns stack traces that led to blocking on synchronization primitives", + "operationId": "pprof-blocking", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/cmdline": { + "get": { + "summary": "Returns the running program's command line.", + "description": "Returns the running program's command line, with arguments separated by NUL bytes.", + "operationId": "pprof-command-line", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/goroutine": { + "get": { + "summary": "Returns stack traces of all current goroutines.", + "description": "Returns stack traces of all current goroutines.", + "operationId": "pprof-goroutines", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/heap": { + "get": { + "summary": "Returns a sampling of memory allocations of live object.", + "description": "Returns a sampling of memory allocations of live object.", + "operationId": "pprof-memory-allocations-live", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/mutex": { + "get": { + "summary": "Returns stack traces of holders of contended mutexes", + "description": "Returns stack traces of holders of contended mutexes", + "operationId": "pprof-mutexes", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/profile": { + "get": { + "summary": "Returns a pprof-formatted cpu profile payload.", + "description": "Returns a pprof-formatted cpu profile payload. Profiling lasts for duration specified in seconds GET parameter, or for 30 seconds if not specified.", + "operationId": "pprof-cpu-profile", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/symbol": { + "get": { + "summary": "Returns the program counters listed in the request.", + "description": "Returns the program counters listed in the request.", + "operationId": "pprof-symbols", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/threadcreate": { + "get": { + "summary": "Returns stack traces that led to the creation of new OS threads", + "description": "Returns stack traces that led to the creation of new OS threads", + "operationId": "pprof-thread-creations", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/pprof/trace": { + "get": { + "summary": "Returns the execution trace in binary form.", + "description": "Returns the execution trace in binary form. Tracing lasts for duration specified in seconds GET parameter, or for 1 second if not specified.", + "operationId": "pprof-execution-trace", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/quotas/config": { + "description": "Create, update and read the quota configuration.", + "get": { + "operationId": "rate-limit-quotas-read-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitQuotasReadConfigurationResponse" + } + } + } + } + } + }, + "post": { + "operationId": "rate-limit-quotas-configure", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitQuotasConfigureRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/quotas/rate-limit": { + "description": "Lists the names of all the rate limit quotas.", + "get": { + "operationId": "rate-limit-quotas-list", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitQuotasListResponse" + } + } + } + } + } + } + }, + "/sys/quotas/rate-limit/{name}": { + "description": "Get, create or update rate limit resource quota for an optional namespace or mount.", + "parameters": [ + { + "name": "name", + "description": "Name of the quota rule.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "operationId": "rate-limit-quotas-read", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitQuotasReadResponse" + } + } + } + } + } + }, + "post": { + "operationId": "rate-limit-quotas-write", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RateLimitQuotasWriteRequest" + } + } + } + }, + "responses": { + "204": { + "description": "No Content" + } + } + }, + "delete": { + "operationId": "rate-limit-quotas-delete", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/raw": { + "description": "Write, Read, and Delete data directly in the Storage backend.", + "x-vault-sudo": true, + "x-vault-createSupported": true, + "get": { + "summary": "Read the value of the key at the given path.", + "operationId": "raw-read", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RawReadResponse" + } + } + } + } + } + }, + "post": { + "summary": "Update the value of the key at the given path.", + "operationId": "raw-write", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RawWriteRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete the key with given path.", + "operationId": "raw-delete", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/raw/{path}": { + "description": "Write, Read, and Delete data directly in the Storage backend.", + "parameters": [ + { + "name": "path", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "x-vault-createSupported": true, + "get": { + "summary": "Read the value of the key at the given path.", + "operationId": "raw-read-path", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RawReadPathResponse" + } + } + } + } + } + }, + "post": { + "summary": "Update the value of the key at the given path.", + "operationId": "raw-write-path", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RawWritePathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "summary": "Delete the key with given path.", + "operationId": "raw-delete-path", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/rekey/backup": { + "description": "Allows fetching or deleting the backup of the rotated unseal keys.", + "get": { + "summary": "Return the backup copy of PGP-encrypted unseal keys.", + "operationId": "rekey-read-backup-key", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyReadBackupKeyResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Delete the backup copy of PGP-encrypted unseal keys.", + "operationId": "rekey-delete-backup-key", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/rekey/init": { + "x-vault-unauthenticated": true, + "get": { + "summary": "Reads the configuration and progress of the current rekey attempt.", + "operationId": "rekey-attempt-read-progress", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyAttemptReadProgressResponse" + } + } + } + } + } + }, + "post": { + "summary": "Initializes a new rekey attempt.", + "description": "Only a single rekey attempt can take place at a time, and changing the parameters of a rekey requires canceling and starting a new rekey, which will also provide a new nonce.", + "operationId": "rekey-attempt-initialize", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyAttemptInitializeRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyAttemptInitializeResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Cancels any in-progress rekey.", + "description": "This clears the rekey settings as well as any progress made. This must be called to change the parameters of the rekey. Note: verification is still a part of a rekey. If rekeying is canceled during the verification flow, the current unseal keys remain valid.", + "operationId": "rekey-attempt-cancel", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/rekey/recovery-key-backup": { + "description": "Allows fetching or deleting the backup of the rotated unseal keys.", + "get": { + "operationId": "rekey-read-backup-recovery-key", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyReadBackupRecoveryKeyResponse" + } + } + } + } + } + }, + "delete": { + "operationId": "rekey-delete-backup-recovery-key", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/rekey/update": { + "x-vault-unauthenticated": true, + "post": { + "summary": "Enter a single unseal key share to progress the rekey of the OpenBao.", + "operationId": "rekey-attempt-update", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyAttemptUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyAttemptUpdateResponse" + } + } + } + } + } + } + }, + "/sys/rekey/verify": { + "x-vault-unauthenticated": true, + "get": { + "summary": "Read the configuration and progress of the current rekey verification attempt.", + "operationId": "rekey-verification-read-progress", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyVerificationReadProgressResponse" + } + } + } + } + } + }, + "post": { + "summary": "Enter a single new key share to progress the rekey verification operation.", + "operationId": "rekey-verification-update", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyVerificationUpdateRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyVerificationUpdateResponse" + } + } + } + } + } + }, + "delete": { + "summary": "Cancel any in-progress rekey verification operation.", + "description": "This clears any progress made and resets the nonce. Unlike a `DELETE` against `sys/rekey/init`, this only resets the current verification operation, not the entire rekey atttempt.", + "operationId": "rekey-verification-cancel", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RekeyVerificationCancelResponse" + } + } + } + } + } + } + }, + "/sys/remount": { + "description": "Move the mount point of an already-mounted backend, within or across namespaces", + "x-vault-sudo": true, + "post": { + "summary": "Initiate a mount migration", + "operationId": "remount", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemountRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemountResponse" + } + } + } + } + } + } + }, + "/sys/remount/status/{migration_id}": { + "description": "Check the status of a mount move operation", + "parameters": [ + { + "name": "migration_id", + "description": "The ID of the migration operation", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "get": { + "summary": "Check status of a mount migration", + "operationId": "remount-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RemountStatusResponse" + } + } + } + } + } + } + }, + "/sys/renew": { + "description": "Renew a lease on a secret", + "post": { + "summary": "Renews a lease, requesting to extend the lease.", + "operationId": "leases-renew-lease2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRenewLease2Request" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/renew/{url_lease_id}": { + "description": "Renew a lease on a secret", + "parameters": [ + { + "name": "url_lease_id", + "description": "The lease identifier to renew. This is included with a lease.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "summary": "Renews a lease, requesting to extend the lease.", + "operationId": "leases-renew-lease-with-id2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRenewLeaseWithId2Request" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/revoke": { + "description": "Revoke a leased secret immediately", + "post": { + "summary": "Revokes a lease immediately.", + "operationId": "leases-revoke-lease2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRevokeLease2Request" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/revoke-force/{prefix}": { + "description": "Revoke all secrets generated in a given prefix, ignoring errors.", + "parameters": [ + { + "name": "prefix", + "description": "The path to revoke keys under. Example: \"prod/aws/ops\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "post": { + "summary": "Revokes all secrets or tokens generated under a given prefix immediately", + "description": "Unlike `/sys/leases/revoke-prefix`, this path ignores backend errors encountered during revocation. This is potentially very dangerous and should only be used in specific emergency situations where errors in the backend or the connected backend service prevent normal revocation.\n\nBy ignoring these errors, OpenBao abdicates responsibility for ensuring that the issued credentials or secrets are properly revoked and/or cleaned up. Access to this endpoint should be tightly controlled.", + "operationId": "leases-force-revoke-lease-with-prefix2", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/revoke-prefix/{prefix}": { + "description": "Revoke all secrets generated in a given prefix", + "parameters": [ + { + "name": "prefix", + "description": "The path to revoke keys under. Example: \"prod/aws/ops\"", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "x-vault-sudo": true, + "post": { + "summary": "Revokes all secrets (via a lease ID prefix) or tokens (via the tokens' path property) generated under a given prefix immediately.", + "operationId": "leases-revoke-lease-with-prefix2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRevokeLeaseWithPrefix2Request" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/revoke/{url_lease_id}": { + "description": "Revoke a leased secret immediately", + "parameters": [ + { + "name": "url_lease_id", + "description": "The lease identifier to renew. This is included with a lease.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "summary": "Revokes a lease immediately.", + "operationId": "leases-revoke-lease-with-id2", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/LeasesRevokeLeaseWithId2Request" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/rotate": { + "description": "Rotates the backend encryption key used to persist data.", + "x-vault-sudo": true, + "post": { + "operationId": "encryption-key-rotate", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/rotate/config": { + "description": "Configures settings related to the backend encryption key management.", + "get": { + "operationId": "encryption-key-read-rotation-configuration", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EncryptionKeyReadRotationConfigurationResponse" + } + } + } + } + } + }, + "post": { + "operationId": "encryption-key-configure-rotation", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/EncryptionKeyConfigureRotationRequest" + } + } + } + }, + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/seal": { + "description": "Seals the OpenBao instance.", + "post": { + "summary": "Seal the OpenBao instance.", + "operationId": "seal", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "OK" + } + } + } + }, + "/sys/seal-status": { + "description": "Returns the seal status of the OpenBao instance.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Check the seal status of an OpenBao instance.", + "operationId": "seal-status", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/SealStatusResponse" + } + } + } + } + } + } + }, + "/sys/step-down": { + "post": { + "summary": "Cause the node to give up active status.", + "description": "This endpoint forces the node to give up active status. If the node does not have active status, this endpoint does nothing. Note that the node will sleep for ten seconds before attempting to grab the active lock again, but if no standby nodes grab the active lock in the interim, the same node may become the active node again.", + "operationId": "step-down-leader", + "tags": [ + "system" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/sys/tools/hash": { + "description": "Generate a hash sum for input data", + "post": { + "operationId": "generate-hash", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateHashRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateHashResponse" + } + } + } + } + } + } + }, + "/sys/tools/hash/{urlalgorithm}": { + "description": "Generate a hash sum for input data", + "parameters": [ + { + "name": "urlalgorithm", + "description": "Algorithm to use (POST URL parameter)", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "operationId": "generate-hash-with-algorithm", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateHashWithAlgorithmRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateHashWithAlgorithmResponse" + } + } + } + } + } + } + }, + "/sys/tools/random": { + "description": "Generate random bytes", + "post": { + "operationId": "generate-random", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomResponse" + } + } + } + } + } + } + }, + "/sys/tools/random/{source}": { + "description": "Generate random bytes", + "parameters": [ + { + "name": "source", + "description": "Which system to source random data from, ether \"platform\", \"seal\", or \"all\".", + "in": "path", + "schema": { + "type": "string", + "default": "platform" + }, + "required": true + } + ], + "post": { + "operationId": "generate-random-with-source", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomWithSourceRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomWithSourceResponse" + } + } + } + } + } + } + }, + "/sys/tools/random/{source}/{urlbytes}": { + "description": "Generate random bytes", + "parameters": [ + { + "name": "source", + "description": "Which system to source random data from, ether \"platform\", \"seal\", or \"all\".", + "in": "path", + "schema": { + "type": "string", + "default": "platform" + }, + "required": true + }, + { + "name": "urlbytes", + "description": "The number of bytes to generate (POST URL parameter)", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "operationId": "generate-random-with-source-and-bytes", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomWithSourceAndBytesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomWithSourceAndBytesResponse" + } + } + } + } + } + } + }, + "/sys/tools/random/{urlbytes}": { + "description": "Generate random bytes", + "parameters": [ + { + "name": "urlbytes", + "description": "The number of bytes to generate (POST URL parameter)", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + } + ], + "post": { + "operationId": "generate-random-with-bytes", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomWithBytesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/GenerateRandomWithBytesResponse" + } + } + } + } + } + } + }, + "/sys/unseal": { + "description": "Unseals the OpenBao instance.", + "x-vault-unauthenticated": true, + "post": { + "summary": "Unseal the OpenBao instance.", + "operationId": "unseal", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnsealRequest" + } + } + } + }, + "responses": { + "200": { + "description": "", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnsealResponse" + } + } + } + } + } + } + }, + "/sys/version-history": { + "description": "List historical version changes sorted by installation time in ascending order.", + "get": { + "summary": "Returns map of historical version change entries", + "operationId": "version-history", + "tags": [ + "system" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/VersionHistoryResponse" + } + } + } + } + } + } + }, + "/sys/wrapping/lookup": { + "description": "Looks up the properties of a response-wrapped token.", + "x-vault-unauthenticated": true, + "get": { + "summary": "Look up wrapping properties for the requester's token.", + "operationId": "read-wrapping-properties2", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadWrappingProperties2Response" + } + } + } + } + } + }, + "post": { + "summary": "Look up wrapping properties for the given token.", + "operationId": "read-wrapping-properties", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadWrappingPropertiesRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK", + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/ReadWrappingPropertiesResponse" + } + } + } + } + } + } + }, + "/sys/wrapping/rewrap": { + "description": "Rotates a response-wrapped token.", + "post": { + "operationId": "rewrap", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/RewrapRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/sys/wrapping/unwrap": { + "description": "Unwraps a response-wrapped token.", + "post": { + "operationId": "unwrap", + "tags": [ + "system" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/UnwrapRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + }, + "204": { + "description": "No content" + } + } + } + }, + "/sys/wrapping/wrap": { + "description": "Response-wraps an arbitrary JSON object.", + "post": { + "operationId": "wrap", + "tags": [ + "system" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/{secret_mount_path}/^.*$": { + "parameters": [ + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ] + }, + "/{secret_mount_path}/config": { + "description": "Configures settings for the KV store", + "parameters": [ + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "summary": "Read the backend level settings.", + "operationId": "kv-read-config", + "tags": [ + "secrets" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "summary": "Configure backend level settings that are applied to every key in the key-value store.", + "operationId": "kv-write-config", + "tags": [ + "secrets" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KvWriteConfigRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/{secret_mount_path}/data/{path}": { + "description": "Write, Patch, Read, and Delete data in the Key-Value Store.", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "kv-read-data-path", + "tags": [ + "secrets" + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "kv-write-data-path", + "tags": [ + "secrets" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KvWriteDataPathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "kv-delete-data-path", + "tags": [ + "secrets" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/{secret_mount_path}/delete/{path}": { + "description": "Marks one or more versions as deleted in the KV store.", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "post": { + "operationId": "kv-write-delete-path", + "tags": [ + "secrets" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KvWriteDeletePathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/{secret_mount_path}/destroy/{path}": { + "description": "Permanently removes one or more versions in the KV store", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "post": { + "operationId": "kv-write-destroy-path", + "tags": [ + "secrets" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KvWriteDestroyPathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/{secret_mount_path}/detailed-metadata/{path}": { + "description": "Configures settings for the KV store", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "get": { + "operationId": "kv-list-detailed-metadata-path", + "tags": [ + "secrets" + ], + "parameters": [ + { + "name": "list", + "description": "Must be set to `true`", + "in": "query", + "schema": { + "type": "string", + "enum": [ + "true" + ] + }, + "required": true + } + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/{secret_mount_path}/metadata/{path}": { + "description": "Configures settings for the KV store", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "get": { + "operationId": "kv-read-metadata-path", + "tags": [ + "secrets" + ], + "parameters": [ + { + "name": "list", + "description": "Return a list if `true`", + "in": "query", + "schema": { + "type": "string" + } + } + ], + "responses": { + "200": { + "description": "OK" + } + } + }, + "post": { + "operationId": "kv-write-metadata-path", + "tags": [ + "secrets" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KvWriteMetadataPathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + }, + "delete": { + "operationId": "kv-delete-metadata-path", + "tags": [ + "secrets" + ], + "responses": { + "204": { + "description": "empty body" + } + } + } + }, + "/{secret_mount_path}/subkeys/{path}": { + "description": "Read the structure of a secret entry from the Key-Value store with the values removed.", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "get": { + "operationId": "kv-read-subkeys-path", + "tags": [ + "secrets" + ], + "responses": { + "200": { + "description": "OK" + } + } + } + }, + "/{secret_mount_path}/undelete/{path}": { + "description": "Undeletes one or more versions from the KV store.", + "parameters": [ + { + "name": "path", + "description": "Location of the secret.", + "in": "path", + "schema": { + "type": "string" + }, + "required": true + }, + { + "name": "secret_mount_path", + "description": "Path that the backend was mounted at", + "in": "path", + "schema": { + "type": "string", + "default": "secret" + }, + "required": true + } + ], + "x-vault-createSupported": true, + "post": { + "operationId": "kv-write-undelete-path", + "tags": [ + "secrets" + ], + "requestBody": { + "required": true, + "content": { + "application/json": { + "schema": { + "$ref": "#/components/schemas/KvWriteUndeletePathRequest" + } + } + } + }, + "responses": { + "200": { + "description": "OK" + } + } + } + } + }, + "components": { + "schemas": { + "AliasCreateRequest": { + "type": "object", + "properties": { + "canonical_id": { + "type": "string", + "description": "Entity ID to which this alias belongs to" + }, + "entity_id": { + "type": "string", + "description": "Entity ID to which this alias belongs to. This field is deprecated in favor of 'canonical_id'." + }, + "id": { + "type": "string", + "description": "ID of the alias" + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this alias belongs to" + }, + "name": { + "type": "string", + "description": "Name of the alias" + } + } + }, + "AliasUpdateByIdRequest": { + "type": "object", + "properties": { + "canonical_id": { + "type": "string", + "description": "Entity ID to which this alias should be tied to" + }, + "entity_id": { + "type": "string", + "description": "Entity ID to which this alias should be tied to. This field is deprecated in favor of 'canonical_id'." + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this alias belongs to" + }, + "name": { + "type": "string", + "description": "Name of the alias" + } + } + }, + "AuditingCalculateHashRequest": { + "type": "object", + "properties": { + "input": { + "type": "string" + } + } + }, + "AuditingCalculateHashResponse": { + "type": "object", + "properties": { + "hash": { + "type": "string" + } + } + }, + "AuditingEnableDeviceRequest": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "User-friendly description for this audit backend." + }, + "local": { + "type": "boolean", + "description": "Mark the mount as a local mount, which is not replicated and is unaffected by replication.", + "default": false + }, + "options": { + "type": "object", + "description": "Configuration options for the audit backend.", + "format": "kvpairs" + }, + "type": { + "type": "string", + "description": "The type of the backend. Example: \"mysql\"" + } + } + }, + "AuditingEnableRequestHeaderRequest": { + "type": "object", + "properties": { + "hmac": { + "type": "boolean" + } + } + }, + "AuditingListRequestHeadersResponse": { + "type": "object", + "properties": { + "headers": { + "type": "object", + "format": "map" + } + } + }, + "AuthEnableMethodRequest": { + "type": "object", + "properties": { + "config": { + "type": "object", + "description": "Configuration for this mount, such as plugin_name.", + "format": "map" + }, + "description": { + "type": "string", + "description": "User-friendly description for this credential backend." + }, + "external_entropy_access": { + "type": "boolean", + "description": "Whether to give the mount access to OpenBao's external entropy.", + "default": false + }, + "local": { + "type": "boolean", + "description": "Mark the mount as a local mount, which is not replicated and is unaffected by replication.", + "default": false + }, + "options": { + "type": "object", + "description": "The options to pass into the backend. Should be a json object with string keys and values.", + "format": "kvpairs" + }, + "plugin_name": { + "type": "string", + "description": "Name of the auth plugin to use based from the name in the plugin catalog." + }, + "plugin_version": { + "type": "string", + "description": "The semantic version of the plugin to use." + }, + "seal_wrap": { + "type": "boolean", + "description": "Whether to turn on seal wrapping for the mount.", + "default": false + }, + "type": { + "type": "string", + "description": "The type of the backend. Example: \"userpass\"" + } + } + }, + "AuthReadConfigurationResponse": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "config": { + "type": "object", + "format": "map" + }, + "deprecation_status": { + "type": "string" + }, + "description": { + "type": "string" + }, + "external_entropy_access": { + "type": "boolean" + }, + "local": { + "type": "boolean" + }, + "options": { + "type": "object", + "format": "map" + }, + "plugin_version": { + "type": "string" + }, + "running_plugin_version": { + "type": "string" + }, + "running_sha256": { + "type": "string" + }, + "seal_wrap": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + }, + "AuthReadTuningInformationResponse": { + "type": "object", + "properties": { + "allowed_managed_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_response_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "audit_non_hmac_request_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "audit_non_hmac_response_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_lease_ttl": { + "type": "integer" + }, + "description": { + "type": "string" + }, + "external_entropy_access": { + "type": "boolean" + }, + "force_no_cache": { + "type": "boolean" + }, + "listing_visibility": { + "type": "string" + }, + "max_lease_ttl": { + "type": "integer" + }, + "options": { + "type": "object", + "format": "map" + }, + "passthrough_request_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "plugin_version": { + "type": "string" + }, + "token_type": { + "type": "string" + }, + "user_lockout_counter_reset_duration": { + "type": "integer", + "format": "int64" + }, + "user_lockout_disable": { + "type": "boolean" + }, + "user_lockout_duration": { + "type": "integer", + "format": "int64" + }, + "user_lockout_threshold": { + "type": "integer", + "format": "int64" + } + } + }, + "AuthTuneConfigurationParametersRequest": { + "type": "object", + "properties": { + "allowed_response_headers": { + "type": "array", + "description": "A list of headers to whitelist and allow a plugin to set on responses.", + "items": { + "type": "string" + } + }, + "audit_non_hmac_request_keys": { + "type": "array", + "description": "The list of keys in the request data object that will not be HMAC'ed by audit devices.", + "items": { + "type": "string" + } + }, + "audit_non_hmac_response_keys": { + "type": "array", + "description": "The list of keys in the response data object that will not be HMAC'ed by audit devices.", + "items": { + "type": "string" + } + }, + "default_lease_ttl": { + "type": "string", + "description": "The default lease TTL for this mount." + }, + "description": { + "type": "string", + "description": "User-friendly description for this credential backend." + }, + "listing_visibility": { + "type": "string", + "description": "Determines the visibility of the mount in the UI-specific listing endpoint. Accepted value are 'unauth' and 'hidden', with the empty default ('') behaving like 'hidden'." + }, + "max_lease_ttl": { + "type": "string", + "description": "The max lease TTL for this mount." + }, + "options": { + "type": "object", + "description": "The options to pass into the backend. Should be a json object with string keys and values.", + "format": "kvpairs" + }, + "passthrough_request_headers": { + "type": "array", + "description": "A list of headers to whitelist and pass from the request to the plugin.", + "items": { + "type": "string" + } + }, + "plugin_version": { + "type": "string", + "description": "The semantic version of the plugin to use." + }, + "token_type": { + "type": "string", + "description": "The type of token to issue (service or batch)." + }, + "user_lockout_config": { + "type": "object", + "description": "The user lockout configuration to pass into the backend. Should be a json object with string keys and values.", + "format": "map" + } + } + }, + "CollectHostInformationResponse": { + "type": "object", + "properties": { + "cpu": { + "type": "array", + "items": { + "type": "object" + } + }, + "cpu_times": { + "type": "array", + "items": { + "type": "object" + } + }, + "disk": { + "type": "array", + "items": { + "type": "object" + } + }, + "host": { + "type": "object", + "format": "map" + }, + "memory": { + "type": "object", + "format": "map" + }, + "timestamp": { + "type": "string", + "format": "date-time" + } + } + }, + "CorsConfigureRequest": { + "type": "object", + "properties": { + "allowed_headers": { + "type": "array", + "description": "A comma-separated string or array of strings indicating headers that are allowed on cross-origin requests.", + "items": { + "type": "string" + } + }, + "allowed_origins": { + "type": "array", + "description": "A comma-separated string or array of strings indicating origins that may make cross-origin requests.", + "items": { + "type": "string" + } + }, + "enable": { + "type": "boolean", + "description": "Enables or disables CORS headers on requests." + } + } + }, + "CorsReadConfigurationResponse": { + "type": "object", + "properties": { + "allowed_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_origins": { + "type": "array", + "items": { + "type": "string" + } + }, + "enabled": { + "type": "boolean" + } + } + }, + "DecodeRequest": { + "type": "object", + "properties": { + "encoded_token": { + "type": "string", + "description": "Specifies the encoded token (result from generate-root)." + }, + "otp": { + "type": "string", + "description": "Specifies the otp code for decode." + } + } + }, + "EncryptionKeyConfigureRotationRequest": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean", + "description": "Whether automatic rotation is enabled." + }, + "interval": { + "type": "integer", + "description": "How long after installation of an active key term that the key will be automatically rotated.", + "format": "seconds" + }, + "max_operations": { + "type": "integer", + "description": "The number of encryption operations performed before the barrier key is automatically rotated.", + "format": "int64" + } + } + }, + "EncryptionKeyReadRotationConfigurationResponse": { + "type": "object", + "properties": { + "enabled": { + "type": "boolean" + }, + "interval": { + "type": "integer", + "format": "seconds" + }, + "max_operations": { + "type": "integer", + "format": "int64" + } + } + }, + "EntityBatchDeleteRequest": { + "type": "object", + "properties": { + "entity_ids": { + "type": "array", + "description": "Entity IDs to delete", + "items": { + "type": "string" + } + } + } + }, + "EntityCreateAliasRequest": { + "type": "object", + "properties": { + "canonical_id": { + "type": "string", + "description": "Entity ID to which this alias belongs" + }, + "custom_metadata": { + "type": "object", + "description": "User provided key-value pairs", + "format": "kvpairs" + }, + "entity_id": { + "type": "string", + "description": "Entity ID to which this alias belongs. This field is deprecated, use canonical_id." + }, + "id": { + "type": "string", + "description": "ID of the entity alias. If set, updates the corresponding entity alias." + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this alias belongs to; unused for a modify" + }, + "name": { + "type": "string", + "description": "Name of the alias; unused for a modify" + } + } + }, + "EntityCreateRequest": { + "type": "object", + "properties": { + "disabled": { + "type": "boolean", + "description": "If set true, tokens tied to this identity will not be able to be used (but will not be revoked)." + }, + "id": { + "type": "string", + "description": "ID of the entity. If set, updates the corresponding existing entity." + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the entity. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "name": { + "type": "string", + "description": "Name of the entity" + }, + "policies": { + "type": "array", + "description": "Policies to be tied to the entity.", + "items": { + "type": "string" + } + } + } + }, + "EntityLookUpRequest": { + "type": "object", + "properties": { + "alias_id": { + "type": "string", + "description": "ID of the alias." + }, + "alias_mount_accessor": { + "type": "string", + "description": "Accessor of the mount to which the alias belongs to. This should be supplied in conjunction with 'alias_name'." + }, + "alias_name": { + "type": "string", + "description": "Name of the alias. This should be supplied in conjunction with 'alias_mount_accessor'." + }, + "id": { + "type": "string", + "description": "ID of the entity." + }, + "name": { + "type": "string", + "description": "Name of the entity." + } + } + }, + "EntityMergeRequest": { + "type": "object", + "properties": { + "conflicting_alias_ids_to_keep": { + "type": "array", + "description": "Alias IDs to keep in case of conflicting aliases. Ignored if no conflicting aliases found", + "items": { + "type": "string" + } + }, + "force": { + "type": "boolean", + "description": "Setting this will follow the 'mine' strategy for merging MFA secrets. If there are secrets of the same type both in entities that are merged from and in entity into which all others are getting merged, secrets in the destination will be unaltered. If not set, this API will throw an error containing all the conflicts." + }, + "from_entity_ids": { + "type": "array", + "description": "Entity IDs which need to get merged", + "items": { + "type": "string" + } + }, + "to_entity_id": { + "type": "string", + "description": "Entity ID into which all the other entities need to get merged" + } + } + }, + "EntityUpdateAliasByIdRequest": { + "type": "object", + "properties": { + "canonical_id": { + "type": "string", + "description": "Entity ID to which this alias should be tied to" + }, + "custom_metadata": { + "type": "object", + "description": "User provided key-value pairs", + "format": "kvpairs" + }, + "entity_id": { + "type": "string", + "description": "Entity ID to which this alias belongs to. This field is deprecated, use canonical_id." + }, + "mount_accessor": { + "type": "string", + "description": "(Unused)" + }, + "name": { + "type": "string", + "description": "(Unused)" + } + } + }, + "EntityUpdateByIdRequest": { + "type": "object", + "properties": { + "disabled": { + "type": "boolean", + "description": "If set true, tokens tied to this identity will not be able to be used (but will not be revoked)." + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the entity. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "name": { + "type": "string", + "description": "Name of the entity" + }, + "policies": { + "type": "array", + "description": "Policies to be tied to the entity.", + "items": { + "type": "string" + } + } + } + }, + "EntityUpdateByNameRequest": { + "type": "object", + "properties": { + "disabled": { + "type": "boolean", + "description": "If set true, tokens tied to this identity will not be able to be used (but will not be revoked)." + }, + "id": { + "type": "string", + "description": "ID of the entity. If set, updates the corresponding existing entity." + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the entity. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "policies": { + "type": "array", + "description": "Policies to be tied to the entity.", + "items": { + "type": "string" + } + } + } + }, + "GenerateHashRequest": { + "type": "object", + "properties": { + "algorithm": { + "type": "string", + "description": "Algorithm to use (POST body parameter). Valid values are: * sha2-224 * sha2-256 * sha2-384 * sha2-512 Defaults to \"sha2-256\".", + "default": "sha2-256" + }, + "format": { + "type": "string", + "description": "Encoding format to use. Can be \"hex\" or \"base64\". Defaults to \"hex\".", + "default": "hex" + }, + "input": { + "type": "string", + "description": "The base64-encoded input data" + }, + "urlalgorithm": { + "type": "string", + "description": "Algorithm to use (POST URL parameter)" + } + } + }, + "GenerateHashResponse": { + "type": "object", + "properties": { + "sum": { + "type": "string" + } + } + }, + "GenerateHashWithAlgorithmRequest": { + "type": "object", + "properties": { + "algorithm": { + "type": "string", + "description": "Algorithm to use (POST body parameter). Valid values are: * sha2-224 * sha2-256 * sha2-384 * sha2-512 Defaults to \"sha2-256\".", + "default": "sha2-256" + }, + "format": { + "type": "string", + "description": "Encoding format to use. Can be \"hex\" or \"base64\". Defaults to \"hex\".", + "default": "hex" + }, + "input": { + "type": "string", + "description": "The base64-encoded input data" + } + } + }, + "GenerateHashWithAlgorithmResponse": { + "type": "object", + "properties": { + "sum": { + "type": "string" + } + } + }, + "GenerateRandomRequest": { + "type": "object", + "properties": { + "bytes": { + "type": "integer", + "description": "The number of bytes to generate (POST body parameter). Defaults to 32 (256 bits).", + "default": 32 + }, + "format": { + "type": "string", + "description": "Encoding format to use. Can be \"hex\" or \"base64\". Defaults to \"base64\".", + "default": "base64" + }, + "source": { + "type": "string", + "description": "Which system to source random data from, ether \"platform\", \"seal\", or \"all\".", + "default": "platform" + }, + "urlbytes": { + "type": "string", + "description": "The number of bytes to generate (POST URL parameter)" + } + } + }, + "GenerateRandomResponse": { + "type": "object", + "properties": { + "random_bytes": { + "type": "string" + } + } + }, + "GenerateRandomWithBytesRequest": { + "type": "object", + "properties": { + "bytes": { + "type": "integer", + "description": "The number of bytes to generate (POST body parameter). Defaults to 32 (256 bits).", + "default": 32 + }, + "format": { + "type": "string", + "description": "Encoding format to use. Can be \"hex\" or \"base64\". Defaults to \"base64\".", + "default": "base64" + }, + "source": { + "type": "string", + "description": "Which system to source random data from, ether \"platform\", \"seal\", or \"all\".", + "default": "platform" + } + } + }, + "GenerateRandomWithBytesResponse": { + "type": "object", + "properties": { + "random_bytes": { + "type": "string" + } + } + }, + "GenerateRandomWithSourceAndBytesRequest": { + "type": "object", + "properties": { + "bytes": { + "type": "integer", + "description": "The number of bytes to generate (POST body parameter). Defaults to 32 (256 bits).", + "default": 32 + }, + "format": { + "type": "string", + "description": "Encoding format to use. Can be \"hex\" or \"base64\". Defaults to \"base64\".", + "default": "base64" + } + } + }, + "GenerateRandomWithSourceAndBytesResponse": { + "type": "object", + "properties": { + "random_bytes": { + "type": "string" + } + } + }, + "GenerateRandomWithSourceRequest": { + "type": "object", + "properties": { + "bytes": { + "type": "integer", + "description": "The number of bytes to generate (POST body parameter). Defaults to 32 (256 bits).", + "default": 32 + }, + "format": { + "type": "string", + "description": "Encoding format to use. Can be \"hex\" or \"base64\". Defaults to \"base64\".", + "default": "base64" + }, + "urlbytes": { + "type": "string", + "description": "The number of bytes to generate (POST URL parameter)" + } + } + }, + "GenerateRandomWithSourceResponse": { + "type": "object", + "properties": { + "random_bytes": { + "type": "string" + } + } + }, + "GroupCreateAliasRequest": { + "type": "object", + "properties": { + "canonical_id": { + "type": "string", + "description": "ID of the group to which this is an alias." + }, + "id": { + "type": "string", + "description": "ID of the group alias." + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this alias belongs to." + }, + "name": { + "type": "string", + "description": "Alias of the group." + } + } + }, + "GroupCreateRequest": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "ID of the group. If set, updates the corresponding existing group." + }, + "member_entity_ids": { + "type": "array", + "description": "Entity IDs to be assigned as group members.", + "items": { + "type": "string" + } + }, + "member_group_ids": { + "type": "array", + "description": "Group IDs to be assigned as group members.", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the group. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "name": { + "type": "string", + "description": "Name of the group." + }, + "policies": { + "type": "array", + "description": "Policies to be tied to the group.", + "items": { + "type": "string" + } + }, + "type": { + "type": "string", + "description": "Type of the group, 'internal' or 'external'. Defaults to 'internal'" + } + } + }, + "GroupLookUpRequest": { + "type": "object", + "properties": { + "alias_id": { + "type": "string", + "description": "ID of the alias." + }, + "alias_mount_accessor": { + "type": "string", + "description": "Accessor of the mount to which the alias belongs to. This should be supplied in conjunction with 'alias_name'." + }, + "alias_name": { + "type": "string", + "description": "Name of the alias. This should be supplied in conjunction with 'alias_mount_accessor'." + }, + "id": { + "type": "string", + "description": "ID of the group." + }, + "name": { + "type": "string", + "description": "Name of the group." + } + } + }, + "GroupUpdateAliasByIdRequest": { + "type": "object", + "properties": { + "canonical_id": { + "type": "string", + "description": "ID of the group to which this is an alias." + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this alias belongs to." + }, + "name": { + "type": "string", + "description": "Alias of the group." + } + } + }, + "GroupUpdateByIdRequest": { + "type": "object", + "properties": { + "member_entity_ids": { + "type": "array", + "description": "Entity IDs to be assigned as group members.", + "items": { + "type": "string" + } + }, + "member_group_ids": { + "type": "array", + "description": "Group IDs to be assigned as group members.", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the group. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "name": { + "type": "string", + "description": "Name of the group." + }, + "policies": { + "type": "array", + "description": "Policies to be tied to the group.", + "items": { + "type": "string" + } + }, + "type": { + "type": "string", + "description": "Type of the group, 'internal' or 'external'. Defaults to 'internal'" + } + } + }, + "GroupUpdateByNameRequest": { + "type": "object", + "properties": { + "id": { + "type": "string", + "description": "ID of the group. If set, updates the corresponding existing group." + }, + "member_entity_ids": { + "type": "array", + "description": "Entity IDs to be assigned as group members.", + "items": { + "type": "string" + } + }, + "member_group_ids": { + "type": "array", + "description": "Group IDs to be assigned as group members.", + "items": { + "type": "string" + } + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the group. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "policies": { + "type": "array", + "description": "Policies to be tied to the group.", + "items": { + "type": "string" + } + }, + "type": { + "type": "string", + "description": "Type of the group, 'internal' or 'external'. Defaults to 'internal'" + } + } + }, + "HaStatusResponse": { + "type": "object", + "properties": { + "nodes": { + "type": "array", + "items": { + "type": "object" + } + } + } + }, + "InitializeSystemRequest": { + "type": "object", + "properties": { + "pgp_keys": { + "type": "array", + "description": "Specifies an array of PGP public keys used to encrypt the output unseal keys. Ordering is preserved. The keys must be base64-encoded from their original binary representation. The size of this array must be the same as `secret_shares`.", + "items": { + "type": "string" + } + }, + "recovery_pgp_keys": { + "type": "array", + "description": "Specifies an array of PGP public keys used to encrypt the output recovery keys. Ordering is preserved. The keys must be base64-encoded from their original binary representation. The size of this array must be the same as `recovery_shares`.", + "items": { + "type": "string" + } + }, + "recovery_shares": { + "type": "integer", + "description": "Specifies the number of shares to split the recovery key into." + }, + "recovery_threshold": { + "type": "integer", + "description": "Specifies the number of shares required to reconstruct the recovery key. This must be less than or equal to `recovery_shares`." + }, + "root_token_pgp_key": { + "type": "string", + "description": "Specifies a PGP public key used to encrypt the initial root token. The key must be base64-encoded from its original binary representation." + }, + "secret_shares": { + "type": "integer", + "description": "Specifies the number of shares to split the unseal key into." + }, + "secret_threshold": { + "type": "integer", + "description": "Specifies the number of shares required to reconstruct the unseal key. This must be less than or equal secret_shares. If using OpenBao HSM with auto-unsealing, this value must be the same as `secret_shares`." + }, + "stored_shares": { + "type": "integer", + "description": "Specifies the number of shares that should be encrypted by the HSM and stored for auto-unsealing. Currently must be the same as `secret_shares`." + } + } + }, + "InternalCountEntitiesResponse": { + "type": "object", + "properties": { + "counters": { + "type": "object", + "format": "map" + } + } + }, + "InternalCountTokensResponse": { + "type": "object", + "properties": { + "counters": { + "type": "object", + "format": "map" + } + } + }, + "InternalGenerateOpenApiDocumentWithParametersRequest": { + "type": "object", + "properties": { + "context": { + "type": "string", + "description": "Context string appended to every operationId" + } + } + }, + "InternalUiListEnabledFeatureFlagsResponse": { + "type": "object", + "properties": { + "feature_flags": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "InternalUiListEnabledVisibleMountsResponse": { + "type": "object", + "properties": { + "auth": { + "type": "object", + "description": "auth mounts", + "format": "map" + }, + "secret": { + "type": "object", + "description": "secret mounts", + "format": "map" + } + } + }, + "InternalUiListNamespacesResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "description": "field is only returned if there are one or more namespaces", + "items": { + "type": "string" + } + } + } + }, + "InternalUiReadMountInformationResponse": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "config": { + "type": "object", + "format": "map" + }, + "deprecation_status": { + "type": "string" + }, + "description": { + "type": "string" + }, + "external_entropy_access": { + "type": "boolean" + }, + "local": { + "type": "boolean" + }, + "options": { + "type": "object", + "format": "map" + }, + "path": { + "type": "string" + }, + "plugin_version": { + "type": "string" + }, + "running_plugin_version": { + "type": "string" + }, + "running_sha256": { + "type": "string" + }, + "seal_wrap": { + "type": "boolean" + }, + "type": { + "type": "string" + }, + "uuid": { + "type": "string" + } + } + }, + "InternalUiReadResultantAclResponse": { + "type": "object", + "properties": { + "exact_paths": { + "type": "object", + "format": "map" + }, + "glob_paths": { + "type": "object", + "format": "map" + }, + "root": { + "type": "boolean" + } + } + }, + "KvWriteConfigRequest": { + "type": "object", + "properties": { + "cas_required": { + "type": "boolean", + "description": "If true, the backend will require the cas parameter to be set for each write" + }, + "delete_version_after": { + "type": "integer", + "description": "If set, the length of time before a version is deleted. A negative duration disables the use of delete_version_after on all keys. A zero duration clears the current setting. Accepts a Go duration format string.", + "format": "seconds" + }, + "max_versions": { + "type": "integer", + "description": "The number of versions to keep for each key. Defaults to 10" + } + } + }, + "KvWriteDataPathRequest": { + "type": "object", + "properties": { + "data": { + "type": "object", + "description": "The contents of the data map will be stored and returned on read.", + "format": "map" + }, + "options": { + "type": "object", + "description": "Options for writing a KV entry. Set the \"cas\" value to use a Check-And-Set operation. If not set the write will be allowed. If set to 0 a write will only be allowed if the key doesn’t exist. If the index is non-zero the write will only be allowed if the key’s current version matches the version specified in the cas parameter.", + "format": "map" + }, + "version": { + "type": "integer", + "description": "If provided during a read, the value at the version number will be returned" + } + } + }, + "KvWriteDeletePathRequest": { + "type": "object", + "properties": { + "versions": { + "type": "array", + "description": "The versions to be archived. The versioned data will not be deleted, but it will no longer be returned in normal get requests.", + "items": { + "type": "integer" + } + } + } + }, + "KvWriteDestroyPathRequest": { + "type": "object", + "properties": { + "versions": { + "type": "array", + "description": "The versions to destroy. Their data will be permanently deleted.", + "items": { + "type": "integer" + } + } + } + }, + "KvWriteMetadataPathRequest": { + "type": "object", + "properties": { + "after": { + "type": "string", + "description": "Optional entry to list begin listing after, not required to exist. Only used for listing." + }, + "cas_required": { + "type": "boolean", + "description": "If true the key will require the cas parameter to be set on all write requests. If false, the backend’s configuration will be used." + }, + "custom_metadata": { + "type": "object", + "description": "User-provided key-value pairs that are used to describe arbitrary and version-agnostic information about a secret.", + "format": "map" + }, + "delete_version_after": { + "type": "integer", + "description": "The length of time before a version is deleted. If not set, the backend's configured delete_version_after is used. Cannot be greater than the backend's delete_version_after. A zero duration clears the current setting. A negative duration will cause an error.", + "format": "seconds" + }, + "limit": { + "type": "integer", + "description": "Optional number of entries to return; defaults to all entries. Only used for listing." + }, + "max_versions": { + "type": "integer", + "description": "The number of versions to keep. If not set, the backend’s configured max version is used." + } + } + }, + "KvWriteUndeletePathRequest": { + "type": "object", + "properties": { + "versions": { + "type": "array", + "description": "The versions to unarchive. The versions will be restored and their data will be returned on normal get requests.", + "items": { + "type": "integer" + } + } + } + }, + "LeaderStatusResponse": { + "type": "object", + "properties": { + "active_time": { + "type": "string", + "format": "date-time" + }, + "ha_enabled": { + "type": "boolean" + }, + "is_self": { + "type": "boolean" + }, + "last_wal": { + "type": "integer", + "format": "int64" + }, + "leader_address": { + "type": "string" + }, + "leader_cluster_address": { + "type": "string" + }, + "performance_standby": { + "type": "boolean" + }, + "performance_standby_last_remote_wal": { + "type": "integer", + "format": "int64" + }, + "raft_applied_index": { + "type": "integer", + "format": "int64" + }, + "raft_committed_index": { + "type": "integer", + "format": "int64" + } + } + }, + "LeasesCountResponse": { + "type": "object", + "properties": { + "counts": { + "type": "integer", + "description": "Number of matching leases per mount" + }, + "lease_count": { + "type": "integer", + "description": "Number of matching leases" + } + } + }, + "LeasesListResponse": { + "type": "object", + "properties": { + "counts": { + "type": "integer", + "description": "Number of matching leases per mount" + }, + "lease_count": { + "type": "integer", + "description": "Number of matching leases" + } + } + }, + "LeasesLookUpResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "description": "A list of lease ids", + "items": { + "type": "string" + } + } + } + }, + "LeasesLookUpWithPrefixResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "description": "A list of lease ids", + "items": { + "type": "string" + } + } + } + }, + "LeasesReadLeaseRequest": { + "type": "object", + "properties": { + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesReadLeaseResponse": { + "type": "object", + "properties": { + "expire_time": { + "type": "string", + "description": "Optional lease expiry time", + "format": "date-time" + }, + "id": { + "type": "string", + "description": "Lease id" + }, + "issue_time": { + "type": "string", + "description": "Timestamp for the lease's issue time", + "format": "date-time" + }, + "last_renewal": { + "type": "string", + "description": "Optional Timestamp of the last time the lease was renewed", + "format": "date-time" + }, + "renewable": { + "type": "boolean", + "description": "True if the lease is able to be renewed" + }, + "ttl": { + "type": "integer", + "description": "Time to Live set for the lease, returns 0 if unset" + } + } + }, + "LeasesRenewLease2Request": { + "type": "object", + "properties": { + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the lease", + "format": "seconds" + }, + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + }, + "url_lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesRenewLeaseRequest": { + "type": "object", + "properties": { + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the lease", + "format": "seconds" + }, + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + }, + "url_lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesRenewLeaseWithId2Request": { + "type": "object", + "properties": { + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the lease", + "format": "seconds" + }, + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesRenewLeaseWithIdRequest": { + "type": "object", + "properties": { + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the lease", + "format": "seconds" + }, + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesRevokeLease2Request": { + "type": "object", + "properties": { + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + }, + "sync": { + "type": "boolean", + "description": "Whether or not to perform the revocation synchronously", + "default": true + }, + "url_lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesRevokeLeaseRequest": { + "type": "object", + "properties": { + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + }, + "sync": { + "type": "boolean", + "description": "Whether or not to perform the revocation synchronously", + "default": true + }, + "url_lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + } + } + }, + "LeasesRevokeLeaseWithId2Request": { + "type": "object", + "properties": { + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + }, + "sync": { + "type": "boolean", + "description": "Whether or not to perform the revocation synchronously", + "default": true + } + } + }, + "LeasesRevokeLeaseWithIdRequest": { + "type": "object", + "properties": { + "lease_id": { + "type": "string", + "description": "The lease identifier to renew. This is included with a lease." + }, + "sync": { + "type": "boolean", + "description": "Whether or not to perform the revocation synchronously", + "default": true + } + } + }, + "LeasesRevokeLeaseWithPrefix2Request": { + "type": "object", + "properties": { + "sync": { + "type": "boolean", + "description": "Whether or not to perform the revocation synchronously", + "default": true + } + } + }, + "LeasesRevokeLeaseWithPrefixRequest": { + "type": "object", + "properties": { + "sync": { + "type": "boolean", + "description": "Whether or not to perform the revocation synchronously", + "default": true + } + } + }, + "LoggersUpdateVerbosityLevelForRequest": { + "type": "object", + "properties": { + "level": { + "type": "string", + "description": "Log verbosity level. Supported values (in order of detail) are \"trace\", \"debug\", \"info\", \"warn\", and \"error\"." + } + } + }, + "LoggersUpdateVerbosityLevelRequest": { + "type": "object", + "properties": { + "level": { + "type": "string", + "description": "Log verbosity level. Supported values (in order of detail) are \"trace\", \"debug\", \"info\", \"warn\", and \"error\"." + } + } + }, + "MfaAdminDestroyTotpSecretRequest": { + "type": "object", + "properties": { + "entity_id": { + "type": "string", + "description": "Identifier of the entity from which the MFA method secret needs to be removed." + }, + "method_id": { + "type": "string", + "description": "The unique identifier for this MFA method." + } + }, + "required": [ + "entity_id", + "method_id" + ] + }, + "MfaAdminGenerateTotpSecretRequest": { + "type": "object", + "properties": { + "entity_id": { + "type": "string", + "description": "Entity ID on which the generated secret needs to get stored." + }, + "method_id": { + "type": "string", + "description": "The unique identifier for this MFA method." + } + }, + "required": [ + "entity_id", + "method_id" + ] + }, + "MfaConfigureDuoMethodRequest": { + "type": "object", + "properties": { + "api_hostname": { + "type": "string", + "description": "API host name for Duo." + }, + "integration_key": { + "type": "string", + "description": "Integration key for Duo." + }, + "method_name": { + "type": "string", + "description": "The unique name identifier for this MFA method." + }, + "push_info": { + "type": "string", + "description": "Push information for Duo." + }, + "secret_key": { + "type": "string", + "description": "Secret key for Duo." + }, + "use_passcode": { + "type": "boolean", + "description": "If true, the user is reminded to use the passcode upon MFA validation. This option does not enforce using the passcode. Defaults to false." + }, + "username_format": { + "type": "string", + "description": "A template string for mapping Identity names to MFA method names. Values to subtitute should be placed in {{}}. For example, \"{{alias.name}}@example.com\". Currently-supported mappings: alias.name: The name returned by the mount configured via the mount_accessor parameter If blank, the Alias's name field will be used as-is." + } + } + }, + "MfaConfigureOktaMethodRequest": { + "type": "object", + "properties": { + "api_token": { + "type": "string", + "description": "Okta API key." + }, + "base_url": { + "type": "string", + "description": "The base domain to use for the Okta API. When not specified in the configuration, \"okta.com\" is used." + }, + "method_name": { + "type": "string", + "description": "The unique name identifier for this MFA method." + }, + "org_name": { + "type": "string", + "description": "Name of the organization to be used in the Okta API." + }, + "primary_email": { + "type": "boolean", + "description": "If true, the username will only match the primary email for the account. Defaults to false." + }, + "production": { + "type": "boolean", + "description": "(DEPRECATED) Use base_url instead." + }, + "username_format": { + "type": "string", + "description": "A template string for mapping Identity names to MFA method names. Values to substitute should be placed in {{}}. For example, \"{{entity.name}}@example.com\". If blank, the Entity's name field will be used as-is." + } + } + }, + "MfaConfigurePingIdMethodRequest": { + "type": "object", + "properties": { + "method_name": { + "type": "string", + "description": "The unique name identifier for this MFA method." + }, + "settings_file_base64": { + "type": "string", + "description": "The settings file provided by Ping, Base64-encoded. This must be a settings file suitable for third-party clients, not the PingID SDK or PingFederate." + }, + "username_format": { + "type": "string", + "description": "A template string for mapping Identity names to MFA method names. Values to subtitute should be placed in {{}}. For example, \"{{alias.name}}@example.com\". Currently-supported mappings: alias.name: The name returned by the mount configured via the mount_accessor parameter If blank, the Alias's name field will be used as-is." + } + } + }, + "MfaConfigureTotpMethodRequest": { + "type": "object", + "properties": { + "algorithm": { + "type": "string", + "description": "The hashing algorithm used to generate the TOTP token. Options include SHA1, SHA256 and SHA512.", + "default": "SHA1" + }, + "digits": { + "type": "integer", + "description": "The number of digits in the generated TOTP token. This value can either be 6 or 8.", + "default": 6 + }, + "issuer": { + "type": "string", + "description": "The name of the key's issuing organization." + }, + "key_size": { + "type": "integer", + "description": "Determines the size in bytes of the generated key.", + "default": 20 + }, + "max_validation_attempts": { + "type": "integer", + "description": "Max number of allowed validation attempts." + }, + "method_name": { + "type": "string", + "description": "The unique name identifier for this MFA method." + }, + "period": { + "type": "integer", + "description": "The length of time used to generate a counter for the TOTP token calculation.", + "format": "seconds", + "default": 30 + }, + "qr_size": { + "type": "integer", + "description": "The pixel size of the generated square QR code.", + "default": 200 + }, + "skew": { + "type": "integer", + "description": "The number of delay periods that are allowed when validating a TOTP token. This value can either be 0 or 1.", + "default": 1 + } + } + }, + "MfaGenerateTotpSecretRequest": { + "type": "object", + "properties": { + "method_id": { + "type": "string", + "description": "The unique identifier for this MFA method." + } + }, + "required": [ + "method_id" + ] + }, + "MfaValidateRequest": { + "type": "object", + "properties": { + "mfa_payload": { + "type": "object", + "description": "A map from MFA method ID to a slice of passcodes or an empty slice if the method does not use passcodes", + "format": "map" + }, + "mfa_request_id": { + "type": "string", + "description": "ID for this MFA request" + } + }, + "required": [ + "mfa_payload", + "mfa_request_id" + ] + }, + "MfaWriteLoginEnforcementRequest": { + "type": "object", + "properties": { + "auth_method_accessors": { + "type": "array", + "description": "Array of auth mount accessor IDs", + "items": { + "type": "string" + } + }, + "auth_method_types": { + "type": "array", + "description": "Array of auth mount types", + "items": { + "type": "string" + } + }, + "identity_entity_ids": { + "type": "array", + "description": "Array of identity entity IDs", + "items": { + "type": "string" + } + }, + "identity_group_ids": { + "type": "array", + "description": "Array of identity group IDs", + "items": { + "type": "string" + } + }, + "mfa_method_ids": { + "type": "array", + "description": "Array of Method IDs that determine what methods will be enforced", + "items": { + "type": "string" + } + } + }, + "required": [ + "mfa_method_ids" + ] + }, + "MountsEnableSecretsEngineRequest": { + "type": "object", + "properties": { + "config": { + "type": "object", + "description": "Configuration for this mount, such as default_lease_ttl and max_lease_ttl.", + "format": "map" + }, + "description": { + "type": "string", + "description": "User-friendly description for this mount." + }, + "external_entropy_access": { + "type": "boolean", + "description": "Whether to give the mount access to OpenBao's external entropy.", + "default": false + }, + "local": { + "type": "boolean", + "description": "Mark the mount as a local mount, which is not replicated and is unaffected by replication.", + "default": false + }, + "options": { + "type": "object", + "description": "The options to pass into the backend. Should be a json object with string keys and values.", + "format": "kvpairs" + }, + "plugin_name": { + "type": "string", + "description": "Name of the plugin to mount based from the name registered in the plugin catalog." + }, + "plugin_version": { + "type": "string", + "description": "The semantic version of the plugin to use." + }, + "seal_wrap": { + "type": "boolean", + "description": "Whether to turn on seal wrapping for the mount.", + "default": false + }, + "type": { + "type": "string", + "description": "The type of the backend. Example: \"passthrough\"" + } + } + }, + "MountsReadConfigurationResponse": { + "type": "object", + "properties": { + "accessor": { + "type": "string" + }, + "config": { + "type": "object", + "description": "Configuration for this mount, such as default_lease_ttl and max_lease_ttl.", + "format": "map" + }, + "deprecation_status": { + "type": "string" + }, + "description": { + "type": "string", + "description": "User-friendly description for this mount." + }, + "external_entropy_access": { + "type": "boolean" + }, + "local": { + "type": "boolean", + "description": "Mark the mount as a local mount, which is not replicated and is unaffected by replication.", + "default": false + }, + "options": { + "type": "object", + "description": "The options to pass into the backend. Should be a json object with string keys and values.", + "format": "kvpairs" + }, + "plugin_version": { + "type": "string", + "description": "The semantic version of the plugin to use." + }, + "running_plugin_version": { + "type": "string" + }, + "running_sha256": { + "type": "string" + }, + "seal_wrap": { + "type": "boolean", + "description": "Whether to turn on seal wrapping for the mount.", + "default": false + }, + "type": { + "type": "string", + "description": "The type of the backend. Example: \"passthrough\"" + }, + "uuid": { + "type": "string" + } + } + }, + "MountsReadTuningInformationResponse": { + "type": "object", + "properties": { + "allowed_managed_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_response_headers": { + "type": "array", + "description": "A list of headers to whitelist and allow a plugin to set on responses.", + "items": { + "type": "string" + } + }, + "audit_non_hmac_request_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "audit_non_hmac_response_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "default_lease_ttl": { + "type": "integer", + "description": "The default lease TTL for this mount." + }, + "description": { + "type": "string", + "description": "User-friendly description for this credential backend." + }, + "external_entropy_access": { + "type": "boolean" + }, + "force_no_cache": { + "type": "boolean" + }, + "listing_visibility": { + "type": "string" + }, + "max_lease_ttl": { + "type": "integer", + "description": "The max lease TTL for this mount." + }, + "options": { + "type": "object", + "description": "The options to pass into the backend. Should be a json object with string keys and values.", + "format": "kvpairs" + }, + "passthrough_request_headers": { + "type": "array", + "items": { + "type": "string" + } + }, + "plugin_version": { + "type": "string", + "description": "The semantic version of the plugin to use." + }, + "token_type": { + "type": "string", + "description": "The type of token to issue (service or batch)." + }, + "user_lockout_counter_reset_duration": { + "type": "integer", + "format": "int64" + }, + "user_lockout_disable": { + "type": "boolean" + }, + "user_lockout_duration": { + "type": "integer", + "format": "int64" + }, + "user_lockout_threshold": { + "type": "integer", + "format": "int64" + } + } + }, + "MountsTuneConfigurationParametersRequest": { + "type": "object", + "properties": { + "allowed_managed_keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "allowed_response_headers": { + "type": "array", + "description": "A list of headers to whitelist and allow a plugin to set on responses.", + "items": { + "type": "string" + } + }, + "audit_non_hmac_request_keys": { + "type": "array", + "description": "The list of keys in the request data object that will not be HMAC'ed by audit devices.", + "items": { + "type": "string" + } + }, + "audit_non_hmac_response_keys": { + "type": "array", + "description": "The list of keys in the response data object that will not be HMAC'ed by audit devices.", + "items": { + "type": "string" + } + }, + "default_lease_ttl": { + "type": "string", + "description": "The default lease TTL for this mount." + }, + "description": { + "type": "string", + "description": "User-friendly description for this credential backend." + }, + "listing_visibility": { + "type": "string", + "description": "Determines the visibility of the mount in the UI-specific listing endpoint. Accepted value are 'unauth' and 'hidden', with the empty default ('') behaving like 'hidden'." + }, + "max_lease_ttl": { + "type": "string", + "description": "The max lease TTL for this mount." + }, + "options": { + "type": "object", + "description": "The options to pass into the backend. Should be a json object with string keys and values.", + "format": "kvpairs" + }, + "passthrough_request_headers": { + "type": "array", + "description": "A list of headers to whitelist and pass from the request to the plugin.", + "items": { + "type": "string" + } + }, + "plugin_version": { + "type": "string", + "description": "The semantic version of the plugin to use." + }, + "token_type": { + "type": "string", + "description": "The type of token to issue (service or batch)." + }, + "user_lockout_config": { + "type": "object", + "description": "The user lockout configuration to pass into the backend. Should be a json object with string keys and values.", + "format": "map" + } + } + }, + "OidcConfigureRequest": { + "type": "object", + "properties": { + "issuer": { + "type": "string", + "description": "Issuer URL to be used in the iss claim of the token. If not set, OpenBao's app_addr will be used." + } + } + }, + "OidcIntrospectRequest": { + "type": "object", + "properties": { + "client_id": { + "type": "string", + "description": "Optional client_id to verify" + }, + "token": { + "type": "string", + "description": "Token to verify" + } + } + }, + "OidcProviderAuthorizeWithParametersRequest": { + "type": "object", + "properties": { + "client_id": { + "type": "string", + "description": "The ID of the requesting client." + }, + "code_challenge": { + "type": "string", + "description": "The code challenge derived from the code verifier." + }, + "code_challenge_method": { + "type": "string", + "description": "The method that was used to derive the code challenge. The following methods are supported: 'S256', 'plain'. Defaults to 'plain'.", + "default": "plain" + }, + "max_age": { + "type": "integer", + "description": "The allowable elapsed time in seconds since the last time the end-user was actively authenticated." + }, + "nonce": { + "type": "string", + "description": "The value that will be returned in the ID token nonce claim after a token exchange." + }, + "redirect_uri": { + "type": "string", + "description": "The redirection URI to which the response will be sent." + }, + "response_type": { + "type": "string", + "description": "The OIDC authentication flow to be used. The following response types are supported: 'code'" + }, + "scope": { + "type": "string", + "description": "A space-delimited, case-sensitive list of scopes to be requested. The 'openid' scope is required." + }, + "state": { + "type": "string", + "description": "The value used to maintain state between the authentication request and client." + } + }, + "required": [ + "client_id", + "redirect_uri", + "response_type", + "scope" + ] + }, + "OidcProviderTokenRequest": { + "type": "object", + "properties": { + "client_id": { + "type": "string", + "description": "The ID of the requesting client." + }, + "client_secret": { + "type": "string", + "description": "The secret of the requesting client." + }, + "code": { + "type": "string", + "description": "The authorization code received from the provider's authorization endpoint." + }, + "code_verifier": { + "type": "string", + "description": "The code verifier associated with the authorization code." + }, + "grant_type": { + "type": "string", + "description": "The authorization grant type. The following grant types are supported: 'authorization_code'." + }, + "redirect_uri": { + "type": "string", + "description": "The callback location where the authentication response was sent." + } + }, + "required": [ + "code", + "grant_type", + "redirect_uri" + ] + }, + "OidcRotateKeyRequest": { + "type": "object", + "properties": { + "verification_ttl": { + "type": "integer", + "description": "Controls how long the public portion of a key will be available for verification after being rotated. Setting verification_ttl here will override the verification_ttl set on the key.", + "format": "seconds" + } + } + }, + "OidcWriteAssignmentRequest": { + "type": "object", + "properties": { + "entity_ids": { + "type": "array", + "description": "Comma separated string or array of identity entity IDs", + "items": { + "type": "string" + } + }, + "group_ids": { + "type": "array", + "description": "Comma separated string or array of identity group IDs", + "items": { + "type": "string" + } + } + } + }, + "OidcWriteClientRequest": { + "type": "object", + "properties": { + "access_token_ttl": { + "type": "integer", + "description": "The time-to-live for access tokens obtained by the client.", + "format": "seconds", + "default": "24h" + }, + "assignments": { + "type": "array", + "description": "Comma separated string or array of assignment resources.", + "items": { + "type": "string" + } + }, + "client_type": { + "type": "string", + "description": "The client type based on its ability to maintain confidentiality of credentials. The following client types are supported: 'confidential', 'public'. Defaults to 'confidential'.", + "default": "confidential" + }, + "id_token_ttl": { + "type": "integer", + "description": "The time-to-live for ID tokens obtained by the client.", + "format": "seconds", + "default": "24h" + }, + "key": { + "type": "string", + "description": "A reference to a named key resource. Cannot be modified after creation. Defaults to the 'default' key.", + "default": "default" + }, + "redirect_uris": { + "type": "array", + "description": "Comma separated string or array of redirect URIs used by the client. One of these values must exactly match the redirect_uri parameter value used in each authentication request.", + "items": { + "type": "string" + } + } + } + }, + "OidcWriteKeyRequest": { + "type": "object", + "properties": { + "algorithm": { + "type": "string", + "description": "Signing algorithm to use. This will default to RS256.", + "default": "RS256" + }, + "allowed_client_ids": { + "type": "array", + "description": "Comma separated string or array of role client ids allowed to use this key for signing. If empty no roles are allowed. If \"*\" all roles are allowed.", + "items": { + "type": "string" + } + }, + "rotation_period": { + "type": "integer", + "description": "How often to generate a new keypair.", + "format": "seconds", + "default": "24h" + }, + "verification_ttl": { + "type": "integer", + "description": "Controls how long the public portion of a key will be available for verification after being rotated.", + "format": "seconds", + "default": "24h" + } + } + }, + "OidcWriteProviderRequest": { + "type": "object", + "properties": { + "allowed_client_ids": { + "type": "array", + "description": "The client IDs that are permitted to use the provider", + "items": { + "type": "string" + } + }, + "issuer": { + "type": "string", + "description": "Specifies what will be used for the iss claim of ID tokens." + }, + "scopes_supported": { + "type": "array", + "description": "The scopes supported for requesting on the provider", + "items": { + "type": "string" + } + } + } + }, + "OidcWriteRoleRequest": { + "type": "object", + "properties": { + "client_id": { + "type": "string", + "description": "Optional client_id" + }, + "key": { + "type": "string", + "description": "The OIDC key to use for generating tokens. The specified key must already exist." + }, + "template": { + "type": "string", + "description": "The template string to use for generating tokens. This may be in string-ified JSON or base64 format." + }, + "ttl": { + "type": "integer", + "description": "TTL of the tokens generated against the role.", + "format": "seconds", + "default": "24h" + } + }, + "required": [ + "key" + ] + }, + "OidcWriteScopeRequest": { + "type": "object", + "properties": { + "description": { + "type": "string", + "description": "The description of the scope" + }, + "template": { + "type": "string", + "description": "The template string to use for the scope. This may be in string-ified JSON or base64 format." + } + } + }, + "PersonaCreateRequest": { + "type": "object", + "properties": { + "entity_id": { + "type": "string", + "description": "Entity ID to which this persona belongs to" + }, + "id": { + "type": "string", + "description": "ID of the persona" + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the persona. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this persona belongs to" + }, + "name": { + "type": "string", + "description": "Name of the persona" + } + } + }, + "PersonaUpdateByIdRequest": { + "type": "object", + "properties": { + "entity_id": { + "type": "string", + "description": "Entity ID to which this persona should be tied to" + }, + "metadata": { + "type": "object", + "description": "Metadata to be associated with the persona. In CLI, this parameter can be repeated multiple times, and it all gets merged together. For example: bao \u003ccommand\u003e \u003cpath\u003e metadata=key1=value1 metadata=key2=value2", + "format": "kvpairs" + }, + "mount_accessor": { + "type": "string", + "description": "Mount accessor to which this persona belongs to" + }, + "name": { + "type": "string", + "description": "Name of the persona" + } + } + }, + "PluginsCatalogListPluginsResponse": { + "type": "object", + "properties": { + "detailed": { + "type": "object", + "format": "map" + } + } + }, + "PluginsCatalogListPluginsWithTypeResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "description": "List of plugin names in the catalog", + "items": { + "type": "string" + } + } + } + }, + "PluginsCatalogReadPluginConfigurationResponse": { + "type": "object", + "properties": { + "args": { + "type": "array", + "description": "The args passed to plugin command.", + "items": { + "type": "string" + } + }, + "builtin": { + "type": "boolean" + }, + "command": { + "type": "string", + "description": "The command used to start the plugin. The executable defined in this command must exist in OpenBao's plugin directory." + }, + "deprecation_status": { + "type": "string" + }, + "name": { + "type": "string", + "description": "The name of the plugin" + }, + "sha256": { + "type": "string", + "description": "The SHA256 sum of the executable used in the command field. This should be HEX encoded." + }, + "version": { + "type": "string", + "description": "The semantic version of the plugin to use." + } + } + }, + "PluginsCatalogReadPluginConfigurationWithTypeResponse": { + "type": "object", + "properties": { + "args": { + "type": "array", + "description": "The args passed to plugin command.", + "items": { + "type": "string" + } + }, + "builtin": { + "type": "boolean" + }, + "command": { + "type": "string", + "description": "The command used to start the plugin. The executable defined in this command must exist in OpenBao's plugin directory." + }, + "deprecation_status": { + "type": "string" + }, + "name": { + "type": "string", + "description": "The name of the plugin" + }, + "sha256": { + "type": "string", + "description": "The SHA256 sum of the executable used in the command field. This should be HEX encoded." + }, + "version": { + "type": "string", + "description": "The semantic version of the plugin to use." + } + } + }, + "PluginsCatalogRegisterPluginRequest": { + "type": "object", + "properties": { + "args": { + "type": "array", + "description": "The args passed to plugin command.", + "items": { + "type": "string" + } + }, + "command": { + "type": "string", + "description": "The command used to start the plugin. The executable defined in this command must exist in OpenBao's plugin directory." + }, + "env": { + "type": "array", + "description": "The environment variables passed to plugin command. Each entry is of the form \"key=value\".", + "items": { + "type": "string" + } + }, + "sha256": { + "type": "string", + "description": "The SHA256 sum of the executable used in the command field. This should be HEX encoded." + }, + "type": { + "type": "string", + "description": "The type of the plugin, may be auth, secret, or database" + }, + "version": { + "type": "string", + "description": "The semantic version of the plugin to use." + } + } + }, + "PluginsCatalogRegisterPluginWithTypeRequest": { + "type": "object", + "properties": { + "args": { + "type": "array", + "description": "The args passed to plugin command.", + "items": { + "type": "string" + } + }, + "command": { + "type": "string", + "description": "The command used to start the plugin. The executable defined in this command must exist in OpenBao's plugin directory." + }, + "env": { + "type": "array", + "description": "The environment variables passed to plugin command. Each entry is of the form \"key=value\".", + "items": { + "type": "string" + } + }, + "sha256": { + "type": "string", + "description": "The SHA256 sum of the executable used in the command field. This should be HEX encoded." + }, + "version": { + "type": "string", + "description": "The semantic version of the plugin to use." + } + } + }, + "PluginsReloadBackendsRequest": { + "type": "object", + "properties": { + "mounts": { + "type": "array", + "description": "The mount paths of the plugin backends to reload.", + "items": { + "type": "string" + } + }, + "plugin": { + "type": "string", + "description": "The name of the plugin to reload, as registered in the plugin catalog." + }, + "scope": { + "type": "string" + } + } + }, + "PluginsReloadBackendsResponse": { + "type": "object", + "properties": { + "reload_id": { + "type": "string" + } + } + }, + "PoliciesGeneratePasswordFromPasswordPolicyResponse": { + "type": "object", + "properties": { + "password": { + "type": "string" + } + } + }, + "PoliciesListAclPoliciesResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "policies": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PoliciesListPasswordPoliciesResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PoliciesListResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "policies": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "PoliciesReadAclPolicy2Response": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "policy": { + "type": "string" + }, + "rules": { + "type": "string" + } + } + }, + "PoliciesReadAclPolicyResponse": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "policy": { + "type": "string" + }, + "rules": { + "type": "string" + } + } + }, + "PoliciesReadPasswordPolicyResponse": { + "type": "object", + "properties": { + "policy": { + "type": "string" + } + } + }, + "PoliciesWriteAclPolicy2Request": { + "type": "object", + "properties": { + "policy": { + "type": "string", + "description": "The rules of the policy." + }, + "rules": { + "type": "string", + "description": "The rules of the policy.", + "deprecated": true + } + } + }, + "PoliciesWriteAclPolicyRequest": { + "type": "object", + "properties": { + "policy": { + "type": "string", + "description": "The rules of the policy." + } + } + }, + "PoliciesWritePasswordPolicyRequest": { + "type": "object", + "properties": { + "policy": { + "type": "string", + "description": "The password policy" + } + } + }, + "QueryTokenAccessorCapabilitiesRequest": { + "type": "object", + "properties": { + "accessor": { + "type": "string", + "description": "Accessor of the token for which capabilities are being queried." + }, + "path": { + "type": "array", + "description": "Use 'paths' instead.", + "items": { + "type": "string" + }, + "deprecated": true + }, + "paths": { + "type": "array", + "description": "Paths on which capabilities are being queried.", + "items": { + "type": "string" + } + } + } + }, + "QueryTokenCapabilitiesRequest": { + "type": "object", + "properties": { + "path": { + "type": "array", + "description": "Use 'paths' instead.", + "items": { + "type": "string" + }, + "deprecated": true + }, + "paths": { + "type": "array", + "description": "Paths on which capabilities are being queried.", + "items": { + "type": "string" + } + }, + "token": { + "type": "string", + "description": "Token for which capabilities are being queried." + } + } + }, + "QueryTokenSelfCapabilitiesRequest": { + "type": "object", + "properties": { + "path": { + "type": "array", + "description": "Use 'paths' instead.", + "items": { + "type": "string" + }, + "deprecated": true + }, + "paths": { + "type": "array", + "description": "Paths on which capabilities are being queried.", + "items": { + "type": "string" + } + }, + "token": { + "type": "string", + "description": "Token for which capabilities are being queried." + } + } + }, + "RateLimitQuotasConfigureRequest": { + "type": "object", + "properties": { + "enable_rate_limit_audit_logging": { + "type": "boolean", + "description": "If set, starts audit logging of requests that get rejected due to rate limit quota rule violations." + }, + "enable_rate_limit_response_headers": { + "type": "boolean", + "description": "If set, additional rate limit quota HTTP headers will be added to responses." + }, + "rate_limit_exempt_paths": { + "type": "array", + "description": "Specifies the list of exempt paths from all rate limit quotas. If empty no paths will be exempt.", + "items": { + "type": "string" + } + } + } + }, + "RateLimitQuotasListResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "RateLimitQuotasReadConfigurationResponse": { + "type": "object", + "properties": { + "enable_rate_limit_audit_logging": { + "type": "boolean" + }, + "enable_rate_limit_response_headers": { + "type": "boolean" + }, + "rate_limit_exempt_paths": { + "type": "array", + "items": { + "type": "string" + } + } + } + }, + "RateLimitQuotasReadResponse": { + "type": "object", + "properties": { + "block_interval": { + "type": "integer" + }, + "interval": { + "type": "integer" + }, + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "rate": { + "type": "number", + "format": "float" + }, + "role": { + "type": "string" + }, + "type": { + "type": "string" + } + } + }, + "RateLimitQuotasWriteRequest": { + "type": "object", + "properties": { + "block_interval": { + "type": "integer", + "description": "If set, when a client reaches a rate limit threshold, the client will be prohibited from any further requests until after the 'block_interval' has elapsed.", + "format": "seconds" + }, + "interval": { + "type": "integer", + "description": "The duration to enforce rate limiting for (default '1s').", + "format": "seconds" + }, + "path": { + "type": "string", + "description": "Path of the mount or namespace to apply the quota. A blank path configures a global quota. For example namespace1/ adds a quota to a full namespace, namespace1/auth/userpass adds a quota to userpass in namespace1." + }, + "rate": { + "type": "number", + "description": "The maximum number of requests in a given interval to be allowed by the quota rule. The 'rate' must be positive.", + "format": "float" + }, + "role": { + "type": "string", + "description": "Login role to apply this quota to. Note that when set, path must be configured to a valid auth method with a concept of roles." + }, + "type": { + "type": "string", + "description": "Type of the quota rule." + } + } + }, + "RawReadPathResponse": { + "type": "object", + "properties": { + "value": { + "type": "string" + } + } + }, + "RawReadResponse": { + "type": "object", + "properties": { + "value": { + "type": "string" + } + } + }, + "RawWritePathRequest": { + "type": "object", + "properties": { + "after": { + "type": "string", + "description": "Optional entry to list begin listing after, not required to exist. Only used in list operations." + }, + "compressed": { + "type": "boolean" + }, + "compression_type": { + "type": "string" + }, + "encoding": { + "type": "string" + }, + "limit": { + "type": "integer", + "description": "Optional number of entries to return; defaults to all entries. Only used in list operations." + }, + "value": { + "type": "string" + } + } + }, + "RawWriteRequest": { + "type": "object", + "properties": { + "after": { + "type": "string", + "description": "Optional entry to list begin listing after, not required to exist. Only used in list operations." + }, + "compressed": { + "type": "boolean" + }, + "compression_type": { + "type": "string" + }, + "encoding": { + "type": "string" + }, + "limit": { + "type": "integer", + "description": "Optional number of entries to return; defaults to all entries. Only used in list operations." + }, + "path": { + "type": "string" + }, + "value": { + "type": "string" + } + } + }, + "ReadWrappingProperties2Response": { + "type": "object", + "properties": { + "creation_path": { + "type": "string" + }, + "creation_time": { + "type": "string", + "format": "date-time" + }, + "creation_ttl": { + "type": "integer", + "format": "seconds" + } + } + }, + "ReadWrappingPropertiesRequest": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "ReadWrappingPropertiesResponse": { + "type": "object", + "properties": { + "creation_path": { + "type": "string" + }, + "creation_time": { + "type": "string", + "format": "date-time" + }, + "creation_ttl": { + "type": "integer", + "format": "seconds" + } + } + }, + "RekeyAttemptInitializeRequest": { + "type": "object", + "properties": { + "backup": { + "type": "boolean", + "description": "Specifies if using PGP-encrypted keys, whether OpenBao should also store a plaintext backup of the PGP-encrypted keys." + }, + "pgp_keys": { + "type": "array", + "description": "Specifies an array of PGP public keys used to encrypt the output unseal keys. Ordering is preserved. The keys must be base64-encoded from their original binary representation. The size of this array must be the same as secret_shares.", + "items": { + "type": "string" + } + }, + "require_verification": { + "type": "boolean", + "description": "Turns on verification functionality" + }, + "secret_shares": { + "type": "integer", + "description": "Specifies the number of shares to split the unseal key into." + }, + "secret_threshold": { + "type": "integer", + "description": "Specifies the number of shares required to reconstruct the unseal key. This must be less than or equal secret_shares. If using OpenBao HSM with auto-unsealing, this value must be the same as secret_shares." + } + } + }, + "RekeyAttemptInitializeResponse": { + "type": "object", + "properties": { + "backup": { + "type": "boolean" + }, + "n": { + "type": "integer" + }, + "nounce": { + "type": "string" + }, + "pgp_fingerprints": { + "type": "array", + "items": { + "type": "string" + } + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "string" + }, + "t": { + "type": "integer" + }, + "verification_nonce": { + "type": "string" + }, + "verification_required": { + "type": "boolean" + } + } + }, + "RekeyAttemptReadProgressResponse": { + "type": "object", + "properties": { + "backup": { + "type": "boolean" + }, + "n": { + "type": "integer" + }, + "nounce": { + "type": "string" + }, + "pgp_fingerprints": { + "type": "array", + "items": { + "type": "string" + } + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "string" + }, + "t": { + "type": "integer" + }, + "verification_nonce": { + "type": "string" + }, + "verification_required": { + "type": "boolean" + } + } + }, + "RekeyAttemptUpdateRequest": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Specifies a single unseal key share." + }, + "nonce": { + "type": "string", + "description": "Specifies the nonce of the rekey attempt." + } + } + }, + "RekeyAttemptUpdateResponse": { + "type": "object", + "properties": { + "backup": { + "type": "boolean" + }, + "complete": { + "type": "boolean" + }, + "keys": { + "type": "array", + "items": { + "type": "string" + } + }, + "keys_base64": { + "type": "array", + "items": { + "type": "string" + } + }, + "n": { + "type": "integer" + }, + "nounce": { + "type": "string" + }, + "pgp_fingerprints": { + "type": "array", + "items": { + "type": "string" + } + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "string" + }, + "t": { + "type": "integer" + }, + "verification_nonce": { + "type": "string" + }, + "verification_required": { + "type": "boolean" + } + } + }, + "RekeyReadBackupKeyResponse": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "format": "map" + }, + "keys_base64": { + "type": "object", + "format": "map" + }, + "nonce": { + "type": "string" + } + } + }, + "RekeyReadBackupRecoveryKeyResponse": { + "type": "object", + "properties": { + "keys": { + "type": "object", + "format": "map" + }, + "keys_base64": { + "type": "object", + "format": "map" + }, + "nonce": { + "type": "string" + } + } + }, + "RekeyVerificationCancelResponse": { + "type": "object", + "properties": { + "n": { + "type": "integer" + }, + "nounce": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "started": { + "type": "string" + }, + "t": { + "type": "integer" + } + } + }, + "RekeyVerificationReadProgressResponse": { + "type": "object", + "properties": { + "n": { + "type": "integer" + }, + "nounce": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "started": { + "type": "string" + }, + "t": { + "type": "integer" + } + } + }, + "RekeyVerificationUpdateRequest": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Specifies a single unseal share key from the new set of shares." + }, + "nonce": { + "type": "string", + "description": "Specifies the nonce of the rekey verification operation." + } + } + }, + "RekeyVerificationUpdateResponse": { + "type": "object", + "properties": { + "complete": { + "type": "boolean" + }, + "nounce": { + "type": "string" + } + } + }, + "RemountRequest": { + "type": "object", + "properties": { + "from": { + "type": "string", + "description": "The previous mount point." + }, + "to": { + "type": "string", + "description": "The new mount point." + } + } + }, + "RemountResponse": { + "type": "object", + "properties": { + "migration_id": { + "type": "string" + } + } + }, + "RemountStatusResponse": { + "type": "object", + "properties": { + "migration_id": { + "type": "string" + }, + "migration_info": { + "type": "object", + "format": "map" + } + } + }, + "RewrapRequest": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "RootTokenGenerationInitialize2Request": { + "type": "object", + "properties": { + "pgp_key": { + "type": "string", + "description": "Specifies a base64-encoded PGP public key." + } + } + }, + "RootTokenGenerationInitialize2Response": { + "type": "object", + "properties": { + "complete": { + "type": "boolean" + }, + "encoded_root_token": { + "type": "string" + }, + "encoded_token": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "otp": { + "type": "string" + }, + "otp_length": { + "type": "integer" + }, + "pgp_fingerprint": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "boolean" + } + } + }, + "RootTokenGenerationInitializeRequest": { + "type": "object", + "properties": { + "pgp_key": { + "type": "string", + "description": "Specifies a base64-encoded PGP public key." + } + } + }, + "RootTokenGenerationInitializeResponse": { + "type": "object", + "properties": { + "complete": { + "type": "boolean" + }, + "encoded_root_token": { + "type": "string" + }, + "encoded_token": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "otp": { + "type": "string" + }, + "otp_length": { + "type": "integer" + }, + "pgp_fingerprint": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "boolean" + } + } + }, + "RootTokenGenerationReadProgress2Response": { + "type": "object", + "properties": { + "complete": { + "type": "boolean" + }, + "encoded_root_token": { + "type": "string" + }, + "encoded_token": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "otp": { + "type": "string" + }, + "otp_length": { + "type": "integer" + }, + "pgp_fingerprint": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "boolean" + } + } + }, + "RootTokenGenerationReadProgressResponse": { + "type": "object", + "properties": { + "complete": { + "type": "boolean" + }, + "encoded_root_token": { + "type": "string" + }, + "encoded_token": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "otp": { + "type": "string" + }, + "otp_length": { + "type": "integer" + }, + "pgp_fingerprint": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "boolean" + } + } + }, + "RootTokenGenerationUpdateRequest": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Specifies a single unseal key share." + }, + "nonce": { + "type": "string", + "description": "Specifies the nonce of the attempt." + } + } + }, + "RootTokenGenerationUpdateResponse": { + "type": "object", + "properties": { + "complete": { + "type": "boolean" + }, + "encoded_root_token": { + "type": "string" + }, + "encoded_token": { + "type": "string" + }, + "nonce": { + "type": "string" + }, + "otp": { + "type": "string" + }, + "otp_length": { + "type": "integer" + }, + "pgp_fingerprint": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "required": { + "type": "integer" + }, + "started": { + "type": "boolean" + } + } + }, + "SealStatusResponse": { + "type": "object", + "properties": { + "build_date": { + "type": "string" + }, + "cluster_id": { + "type": "string" + }, + "cluster_name": { + "type": "string" + }, + "initialized": { + "type": "boolean" + }, + "migration": { + "type": "boolean" + }, + "n": { + "type": "integer" + }, + "nonce": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "recovery_seal": { + "type": "boolean" + }, + "sealed": { + "type": "boolean" + }, + "storage_type": { + "type": "string" + }, + "t": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "TokenCreateAgainstRoleRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "description": "Name to associate with this token" + }, + "entity_alias": { + "type": "string", + "description": "Name of the entity alias to associate with this token" + }, + "explicit_max_ttl": { + "type": "string", + "description": "Explicit Max TTL of this token" + }, + "id": { + "type": "string", + "description": "Value for the token" + }, + "lease": { + "type": "string", + "description": "Use 'ttl' instead", + "deprecated": true + }, + "meta": { + "type": "object", + "description": "Arbitrary key=value metadata to associate with the token", + "format": "kvpairs" + }, + "no_default_policy": { + "type": "boolean", + "description": "Do not include default policy for this token" + }, + "no_parent": { + "type": "boolean", + "description": "Create the token with no parent" + }, + "num_uses": { + "type": "integer", + "description": "Max number of uses for this token" + }, + "period": { + "type": "string", + "description": "Renew period" + }, + "policies": { + "type": "array", + "description": "List of policies for the token", + "items": { + "type": "string" + } + }, + "renewable": { + "type": "boolean", + "description": "Allow token to be renewed past its initial TTL up to system/mount maximum TTL", + "default": true + }, + "ttl": { + "type": "string", + "description": "Time to live for this token" + }, + "type": { + "type": "string", + "description": "Token type" + } + } + }, + "TokenCreateOrphanRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "description": "Name to associate with this token" + }, + "entity_alias": { + "type": "string", + "description": "Name of the entity alias to associate with this token" + }, + "explicit_max_ttl": { + "type": "string", + "description": "Explicit Max TTL of this token" + }, + "id": { + "type": "string", + "description": "Value for the token" + }, + "lease": { + "type": "string", + "description": "Use 'ttl' instead", + "deprecated": true + }, + "meta": { + "type": "object", + "description": "Arbitrary key=value metadata to associate with the token", + "format": "kvpairs" + }, + "no_default_policy": { + "type": "boolean", + "description": "Do not include default policy for this token" + }, + "no_parent": { + "type": "boolean", + "description": "Create the token with no parent" + }, + "num_uses": { + "type": "integer", + "description": "Max number of uses for this token" + }, + "period": { + "type": "string", + "description": "Renew period" + }, + "policies": { + "type": "array", + "description": "List of policies for the token", + "items": { + "type": "string" + } + }, + "renewable": { + "type": "boolean", + "description": "Allow token to be renewed past its initial TTL up to system/mount maximum TTL", + "default": true + }, + "ttl": { + "type": "string", + "description": "Time to live for this token" + }, + "type": { + "type": "string", + "description": "Token type" + } + } + }, + "TokenCreateRequest": { + "type": "object", + "properties": { + "display_name": { + "type": "string", + "description": "Name to associate with this token" + }, + "entity_alias": { + "type": "string", + "description": "Name of the entity alias to associate with this token" + }, + "explicit_max_ttl": { + "type": "string", + "description": "Explicit Max TTL of this token" + }, + "id": { + "type": "string", + "description": "Value for the token" + }, + "lease": { + "type": "string", + "description": "Use 'ttl' instead", + "deprecated": true + }, + "meta": { + "type": "object", + "description": "Arbitrary key=value metadata to associate with the token", + "format": "kvpairs" + }, + "no_default_policy": { + "type": "boolean", + "description": "Do not include default policy for this token" + }, + "no_parent": { + "type": "boolean", + "description": "Create the token with no parent" + }, + "num_uses": { + "type": "integer", + "description": "Max number of uses for this token" + }, + "period": { + "type": "string", + "description": "Renew period" + }, + "policies": { + "type": "array", + "description": "List of policies for the token", + "items": { + "type": "string" + } + }, + "renewable": { + "type": "boolean", + "description": "Allow token to be renewed past its initial TTL up to system/mount maximum TTL", + "default": true + }, + "ttl": { + "type": "string", + "description": "Time to live for this token" + }, + "type": { + "type": "string", + "description": "Token type" + } + } + }, + "TokenLookUpAccessorRequest": { + "type": "object", + "properties": { + "accessor": { + "type": "string", + "description": "Accessor of the token to look up (request body)" + } + } + }, + "TokenLookUpRequest": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Token to lookup (POST request body)" + } + } + }, + "TokenLookUpSelf2Request": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Token to look up (unused, does not need to be set)" + } + } + }, + "TokenRenewAccessorRequest": { + "type": "object", + "properties": { + "accessor": { + "type": "string", + "description": "Accessor of the token to renew (request body)" + }, + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the token expiration", + "format": "seconds", + "default": 0 + } + } + }, + "TokenRenewRequest": { + "type": "object", + "properties": { + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the token expiration", + "format": "seconds", + "default": 0 + }, + "token": { + "type": "string", + "description": "Token to renew (request body)" + } + } + }, + "TokenRenewSelfRequest": { + "type": "object", + "properties": { + "increment": { + "type": "integer", + "description": "The desired increment in seconds to the token expiration", + "format": "seconds", + "default": 0 + }, + "token": { + "type": "string", + "description": "Token to renew (unused, does not need to be set)" + } + } + }, + "TokenRevokeAccessorRequest": { + "type": "object", + "properties": { + "accessor": { + "type": "string", + "description": "Accessor of the token (request body)" + } + } + }, + "TokenRevokeOrphanRequest": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Token to revoke (request body)" + } + } + }, + "TokenRevokeRequest": { + "type": "object", + "properties": { + "token": { + "type": "string", + "description": "Token to revoke (request body)" + } + } + }, + "TokenWriteRoleRequest": { + "type": "object", + "properties": { + "allowed_entity_aliases": { + "type": "array", + "description": "String or JSON list of allowed entity aliases. If set, specifies the entity aliases which are allowed to be used during token generation. This field supports globbing.", + "items": { + "type": "string" + } + }, + "allowed_policies": { + "type": "array", + "description": "If set, tokens can be created with any subset of the policies in this list, rather than the normal semantics of tokens being a subset of the calling token's policies. The parameter is a comma-delimited string of policy names.", + "items": { + "type": "string" + } + }, + "allowed_policies_glob": { + "type": "array", + "description": "If set, tokens can be created with any subset of glob matched policies in this list, rather than the normal semantics of tokens being a subset of the calling token's policies. The parameter is a comma-delimited string of policy name globs.", + "items": { + "type": "string" + } + }, + "bound_cidrs": { + "type": "array", + "description": "Use 'token_bound_cidrs' instead.", + "items": { + "type": "string" + }, + "deprecated": true + }, + "disallowed_policies": { + "type": "array", + "description": "If set, successful token creation via this role will require that no policies in the given list are requested. The parameter is a comma-delimited string of policy names.", + "items": { + "type": "string" + } + }, + "disallowed_policies_glob": { + "type": "array", + "description": "If set, successful token creation via this role will require that no requested policies glob match any of policies in this list. The parameter is a comma-delimited string of policy name globs.", + "items": { + "type": "string" + } + }, + "explicit_max_ttl": { + "type": "integer", + "description": "Use 'token_explicit_max_ttl' instead.", + "format": "seconds", + "deprecated": true + }, + "orphan": { + "type": "boolean", + "description": "If true, tokens created via this role will be orphan tokens (have no parent)" + }, + "path_suffix": { + "type": "string", + "description": "If set, tokens created via this role will contain the given suffix as a part of their path. This can be used to assist use of the 'revoke-prefix' endpoint later on. The given suffix must match the regular expression.\\w[\\w-.]+\\w" + }, + "period": { + "type": "integer", + "description": "Use 'token_period' instead.", + "format": "seconds", + "deprecated": true + }, + "renewable": { + "type": "boolean", + "description": "Tokens created via this role will be renewable or not according to this value. Defaults to \"true\".", + "default": true + }, + "token_bound_cidrs": { + "type": "array", + "description": "Comma separated string or JSON list of CIDR blocks. If set, specifies the blocks of IP addresses which are allowed to use the generated token.", + "items": { + "type": "string" + }, + "x-vault-displayAttrs": { + "name": "Generated Token's Bound CIDRs", + "description": "A list of CIDR blocks. If set, specifies the blocks of IP addresses which are allowed to use the generated token.", + "group": "Tokens" + } + }, + "token_explicit_max_ttl": { + "type": "integer", + "description": "If set, tokens created via this role carry an explicit maximum TTL. During renewal, the current maximum TTL values of the role and the mount are not checked for changes, and any updates to these values will have no effect on the token being renewed.", + "format": "seconds", + "x-vault-displayAttrs": { + "name": "Generated Token's Explicit Maximum TTL", + "group": "Tokens" + } + }, + "token_no_default_policy": { + "type": "boolean", + "description": "If true, the 'default' policy will not automatically be added to generated tokens", + "x-vault-displayAttrs": { + "name": "Do Not Attach 'default' Policy To Generated Tokens", + "group": "Tokens" + } + }, + "token_num_uses": { + "type": "integer", + "description": "The maximum number of times a token may be used, a value of zero means unlimited", + "x-vault-displayAttrs": { + "name": "Maximum Uses of Generated Tokens", + "group": "Tokens" + } + }, + "token_period": { + "type": "integer", + "description": "If set, tokens created via this role will have no max lifetime; instead, their renewal period will be fixed to this value. This takes an integer number of seconds, or a string duration (e.g. \"24h\").", + "format": "seconds", + "x-vault-displayAttrs": { + "name": "Generated Token's Period", + "group": "Tokens" + } + }, + "token_type": { + "type": "string", + "description": "The type of token to generate, service or batch", + "default": "default-service", + "x-vault-displayAttrs": { + "name": "Generated Token's Type", + "group": "Tokens" + } + } + } + }, + "UiHeadersConfigureRequest": { + "type": "object", + "properties": { + "multivalue": { + "type": "boolean", + "description": "Returns multiple values if true" + }, + "values": { + "type": "array", + "description": "The values to set the header.", + "items": { + "type": "string" + } + } + } + }, + "UiHeadersListResponse": { + "type": "object", + "properties": { + "keys": { + "type": "array", + "description": "Lists of configured UI headers. Omitted if list is empty", + "items": { + "type": "string" + } + } + } + }, + "UiHeadersReadConfigurationResponse": { + "type": "object", + "properties": { + "value": { + "type": "string", + "description": "returns the first header value when `multivalue` request parameter is false" + }, + "values": { + "type": "array", + "description": "returns all header values when `multivalue` request parameter is true", + "items": { + "type": "string" + } + } + } + }, + "UnsealRequest": { + "type": "object", + "properties": { + "key": { + "type": "string", + "description": "Specifies a single unseal key share. This is required unless reset is true." + }, + "reset": { + "type": "boolean", + "description": "Specifies if previously-provided unseal keys are discarded and the unseal process is reset." + } + } + }, + "UnsealResponse": { + "type": "object", + "properties": { + "build_date": { + "type": "string" + }, + "cluster_id": { + "type": "string" + }, + "cluster_name": { + "type": "string" + }, + "initialized": { + "type": "boolean" + }, + "migration": { + "type": "boolean" + }, + "n": { + "type": "integer" + }, + "nonce": { + "type": "string" + }, + "progress": { + "type": "integer" + }, + "recovery_seal": { + "type": "boolean" + }, + "sealed": { + "type": "boolean" + }, + "storage_type": { + "type": "string" + }, + "t": { + "type": "integer" + }, + "type": { + "type": "string" + }, + "version": { + "type": "string" + } + } + }, + "UnwrapRequest": { + "type": "object", + "properties": { + "token": { + "type": "string" + } + } + }, + "VersionHistoryResponse": { + "type": "object", + "properties": { + "key_info": { + "type": "object", + "format": "kvpairs" + }, + "keys": { + "type": "array", + "items": { + "type": "string" + } + } + } + } + } + } +} \ No newline at end of file diff --git a/src/engines/kv.rs b/src/engines/kv.rs index 906928f..18aff42 100644 --- a/src/engines/kv.rs +++ b/src/engines/kv.rs @@ -1,45 +1,33 @@ -// TODO: Remove -#![allow(dead_code)] - -pub mod logic; -pub mod structs; +mod structs; +mod data; +mod meta; // #[cfg(test)] // mod tests; - -use crate::{ - common::HttpError, - engines::kv::{logic::body_to_json, structs::*}, - storage::DatabaseDriver, -}; +use crate::storage::DatabaseDriver; use axum::{ + Router, extract::{Path, State}, - http::StatusCode, - response::{IntoResponse, NoContent, Response}, routing::*, - Extension, Json, Router, }; -use log::{error, info, warn}; -use time::UtcDateTime; - -use super::EnginePath; pub fn kv_router(pool: DatabaseDriver) -> Router { Router::new() .route("/config", get(get_config)) .route("/config", post(post_config)) - .route("/data/{*path}", get(get_data)) + .route("/data/{*path}", get(data::get_data)) // .route("/:mount_path/data/*path/", get(get_data)) - .route("/data/{*path}", post(post_data)) - .route("/data/{*path}", put(post_data)) - .route("/data/{*path}", delete(delete_data)) - .route("/delete/{*path}", post(delete_path)) - .route("/destroy/{*path}", post(destroy_path)) - .route("/metadata/{*path}", get(get_meta)) + .route("/data/{*path}", post(data::post_data)) + // Why does HC V SDK expect PUT instead of POST - neither in the docs nor spec + .route("/data/{*path}", put(data::post_data)) + .route("/data/{*path}", delete(data::delete_data)) + .route("/delete/{*path}", post(meta::delete_path)) + .route("/destroy/{*path}", post(meta::destroy_path)) + .route("/metadata/{*path}", get(meta::get_meta)) // .route("/:mount_path/metadata/*path/", get(get_meta)) - .route("/metadata/{*path}", post(post_meta)) - .route("/metadata/{*path}", delete(delete_meta)) + .route("/metadata/{*path}", post(meta::post_meta)) + .route("/metadata/{*path}", delete(meta::delete_meta)) .route("/subkeys/{*path}", get(get_subkeys)) .route("/undelete/{*path}", post(post_undelete)) .with_state(pool) @@ -53,241 +41,6 @@ async fn post_config() -> &'static str { todo!("not implemented") } -async fn get_data( - State(pool): State, - Path(path): Path, - Extension(EnginePath(engine_path)): Extension, -) -> Result { - log::trace!("AAAAAAAAAAAAAAAAAAAA! {path} of engine {engine_path}"); - - match sqlx::query_as!( - KvSecretData, - r#"SELECT secret_data, created_time, deletion_time, version_number, secret_path - FROM kv2_secret_version WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL - ORDER BY version_number DESC LIMIT 1"#, - engine_path, path - ) - .fetch_one(&pool) - .await - { - Ok(secret_content) => { - // let version: i64 = v.get("version_number"); - // let secret_content: HashMap = HashMap::from([ - // // TODO: use sqlx to parse the row to a struct, do not do it manually - // ("secret_data".to_string(), v.get("secret_data")), - // ("created_time".to_string(), v.get("created_time")), - // ("deletion_time".to_string(), v.get("deletion_time")), - // ("version_number".to_string(), version.to_string()), - // ("secret_path".to_string(), v.get("secret_path")), - // ]); - - let data = Wrapper { - data: serde_json::from_str(&secret_content.secret_data).unwrap(), - }; - let return_secret = KvSecretRes { - data, - options: None, - version: Some(secret_content.version_number) - }; - let return_secret = Json(return_secret); - info!("{:?}", return_secret); - - Ok(return_secret.into_response()) - } - Err(e) => match e { - sqlx::Error::RowNotFound => { - error!("Row not found {:?}", e); - // let error_data: HashMap = - // HashMap::from([("error".to_string(), "Secret not found".to_string())]); - // let error_secret = KvSecretRes { - // data: error_data, - // options: None, - // }; - Ok(HttpError::simple( - StatusCode::NOT_FOUND, - "Secret not found within kv2 engine", - )) - } - _ => panic!("{e:?}"), - }, - } -} - -async fn post_data( - State(pool): State, - Path(kv_path): Path, - Extension(EnginePath(engine_path)): Extension, - Json(secret): Json, -) -> Result { - log::debug!( - "Engine: {}, Secret: {}, Content: {}, Version: {:?}, path: {}", - engine_path, - kv_path, - secret.data, - secret.version, //.unwrap_or(0), - kv_path - ); - - let created_time = time::UtcDateTime::now(); - let ts = created_time.unix_timestamp(); - - let mut tx = pool.begin().await.unwrap(); - - let res_m = sqlx::query!(" - INSERT INTO kv2_metadata (engine_path, secret_path, cas_required, created_time, max_versions, updated_time) - VALUES ($1, $2, 0, $3, 100, $3) - ON CONFLICT(engine_path, secret_path) DO NOTHING; - ", engine_path, kv_path, ts).execute(&mut *tx).await.unwrap(); - - let res_r = sqlx::query_file!( - "src/engines/kv/post_secret.sql", - engine_path, - kv_path, - secret.data, - ts, - secret.version, - ) - .fetch_one(&mut *tx) - .await - .unwrap(); - - tx.commit().await.expect("FAILED TO WRITE TX!"); - - warn!("test: {res_m:?} {res_r:?} {}", res_r.version_number); - - let res = KvV2WriteResponse { - created_time: created_time.into(), - custom_metadata: None, - deletion_time: None, - destroyed: false, - version: res_r.version_number, - }; - - Ok(Json(res).into_response()) -} - -/* mock for return -async fn post_data( - Path(kv_path): Path, - Extension(mount_path): Extension, - Json(body): Json, -) -> Json { - trace!( - "Secret: {}, Content: {:#?}, path: {}", - kv_path, - body.data, - // body.version.unwrap_or(0), - mount_path, - ); - - let res = KvSecretRes { - data: KvSecretResData { - created_time: chrono::Utc::now(), - custom_metadata: None, - deletion_time: None, - destroyed: false, - version: 1, - }, - }; - - Json(res) -} */ - -/// TODO: soft delete the secret version at path. can be undone with undelete_secret -// https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#delete-latest-version-of-secret -// https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#delete-secret-versions -async fn delete_data( - State(pool): State, - Path(path): Path, - Extension(EnginePath(engine_path)): Extension, -) -> Result { - log::debug!("Secret: {}, path: {}", path, path); - - let del_time = UtcDateTime::now().unix_timestamp(); - - let mut tx = pool.begin().await.unwrap(); - - // TODO: Find a better way - let latest_version = sqlx::query!( - r#" - SELECT version_number AS latest_version FROM kv2_secret_version - WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL - ORDER BY version_number DESC LIMIT 1"#, - engine_path, - path, - ) - .fetch_optional(&mut *tx) - .await - .unwrap(); - - let latest_version = match latest_version { - Some(v) => v.latest_version, - None => { - return Err(HttpError::simple( - StatusCode::NOT_FOUND, - "No secret version found which could be deleted", - )); - } - }; - - let u = sqlx::query!( - r#" - UPDATE kv2_secret_version - SET deletion_time = $4 - WHERE engine_path = $1 AND secret_path = $2 - AND version_number = $3 - "#, - engine_path, - path, - latest_version, - del_time - ) - .execute(&mut *tx) - .await; - - if let Err(e) = u { - error!("Strange - a version to be deleted has been found but could not be found to set deletion.\n\t{e:?}"); - // Not commited transactions will be aborted upon drop - // tx.rollback().await.unwrap(); - return Err(HttpError::simple( - StatusCode::INTERNAL_SERVER_ERROR, - "A version to be deleted was found but could not be deleted", - )); - } - - tx.commit().await.unwrap(); - - info!("Secret {path} version {latest_version} of {engine_path} engine deleted! {u:?}"); - - Ok(NoContent.into_response()) -} - -async fn delete_path() -> &'static str { - todo!("not implemented") -} - -async fn destroy_path() -> &'static str { - todo!("not implemented") -} - -async fn get_meta() -> &'static str { - todo!("not implemented") -} - -async fn post_meta( - State(pool): State, - Path((mount_path, kv_path)): Path<(String, String)>, - body: String, -) -> &'static str { - let body_json = body_to_json(body); - let meta_data: SecretMeta = Default::default(); - todo!("not implemented") -} - -async fn delete_meta() -> &'static str { - todo!("not implemented") -} - async fn get_subkeys() -> &'static str { todo!("not implemented") } diff --git a/src/engines/kv/data.rs b/src/engines/kv/data.rs new file mode 100644 index 0000000..faf0dd5 --- /dev/null +++ b/src/engines/kv/data.rs @@ -0,0 +1,215 @@ +use super::structs::KvV2WriteRequest; +use crate::{ + DatabaseDriver, + common::HttpError, + engines::{ + EnginePath, + kv::structs::{KvSecretData, KvSecretRes, KvV2WriteResponse, Wrapper}, + }, +}; +use axum::{ + Extension, Json, + extract::{Path, Query, State}, + http::StatusCode, + response::{IntoResponse, NoContent, Response}, +}; +use log::{error, info, warn}; +use serde::Deserialize; +use time::UtcDateTime; + +#[derive(Deserialize)] +pub struct GetDataQuery { + #[serde(default)] + /// Version of secret requested to be read. + /// Default `0`, to get the most recent version. + pub version: u32, +} + +pub async fn get_data( + State(pool): State, + Query(params): Query, + Path(path): Path, + Extension(EnginePath(engine_path)): Extension, +) -> Result { + let res = if params.version == 0 { + // With specific version + sqlx::query_as!( + KvSecretData, + r#"SELECT secret_data, created_time, deletion_time, version_number, secret_path + FROM kv2_secret_version WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL + AND version_number = $3"#, + engine_path, path, params.version).fetch_one(&pool).await + } else { + // Without specific version + sqlx::query_as!( + KvSecretData, + r#"SELECT secret_data, created_time, deletion_time, version_number, secret_path + FROM kv2_secret_version WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL + ORDER BY version_number DESC LIMIT 1"#, + engine_path, path).fetch_one(&pool).await + }; + + match res { + Ok(secret_content) => { + let data = Wrapper { + data: serde_json::from_str(&secret_content.secret_data).unwrap(), + }; + let return_secret = KvSecretRes { + data, + options: None, + version: Some(secret_content.version_number), + }; + let return_secret = Json(return_secret); + info!("{:?}", return_secret); + + Ok(return_secret.into_response()) + } + Err(e) => match e { + sqlx::Error::RowNotFound => { + error!("Row not found {:?}", e); + Ok(HttpError::simple( + StatusCode::NOT_FOUND, + "Secret not found within kv2 engine", + )) + } + _ => panic!("{e:?}"), + }, + } +} + +pub async fn post_data( + State(pool): State, + Path(kv_path): Path, + Extension(EnginePath(engine_path)): Extension, + Json(secret): Json, +) -> Result { + log::debug!( + "Engine: {}, Secret: {}, Content: {}, Version: {:?}, path: {}", + engine_path, + kv_path, + secret.data, + secret.version, //.unwrap_or(0), + kv_path + ); + + let created_time = time::UtcDateTime::now(); + let ts = created_time.unix_timestamp(); + + let mut tx = pool.begin().await.unwrap(); + + let res_m = sqlx::query!(" + INSERT INTO kv2_metadata (engine_path, secret_path, cas_required, created_time, max_versions, updated_time) + VALUES ($1, $2, 0, $3, 100, $3) + ON CONFLICT(engine_path, secret_path) DO NOTHING; + ", engine_path, kv_path, ts).execute(&mut *tx).await.unwrap(); + + let res_r = sqlx::query_file!( + "src/engines/kv/post_secret.sql", + engine_path, + kv_path, + secret.data, + ts, + secret.version, + ) + .fetch_one(&mut *tx) + .await + .unwrap(); + + tx.commit().await.expect("FAILED TO WRITE TX!"); + + warn!("test: {res_m:?} {res_r:?} {}", res_r.version_number); + + let res = KvV2WriteResponse { + created_time: created_time.into(), + custom_metadata: None, + deletion_time: None, + destroyed: false, + version: res_r.version_number, + }; + + Ok(Json(res).into_response()) +} + +/// TODO: soft delete the secret version at path. can be undone with undelete_secret +// https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#delete-latest-version-of-secret +// https://developer.hashicorp.com/vault/api-docs/secret/kv/kv-v2#delete-secret-versions +pub async fn delete_data( + State(pool): State, + Path(path): Path, + Extension(EnginePath(engine_path)): Extension, +) -> Result { + log::debug!("Secret: {}, path: {}", path, path); + + let del_time = UtcDateTime::now().unix_timestamp(); + + let mut tx = pool.begin().await.unwrap(); + + // TODO: Find a better way + let latest_version = sqlx::query!( + r#" + SELECT version_number AS latest_version FROM kv2_secret_version + WHERE engine_path = $1 AND secret_path = $2 AND deletion_time IS NULL + ORDER BY version_number DESC LIMIT 1"#, + engine_path, + path, + ) + .fetch_optional(&mut *tx) + .await + .unwrap(); + + let latest_version = match latest_version { + Some(v) => v.latest_version, + None => { + return Err(HttpError::simple( + StatusCode::NOT_FOUND, + "No secret version found which could be deleted", + )); + } + }; + + let u = sqlx::query!( + r#" + UPDATE kv2_secret_version + SET deletion_time = $4 + WHERE engine_path = $1 AND secret_path = $2 + AND version_number = $3 + "#, + engine_path, + path, + latest_version, + del_time + ) + .execute(&mut *tx) + .await; + + if let Err(e) = u { + error!( + "Strange - a version to be deleted has been found but could not be found to set deletion.\n\t{e:?}" + ); + // Not commited transactions will be aborted upon drop + // tx.rollback().await.unwrap(); + return Err(HttpError::simple( + StatusCode::INTERNAL_SERVER_ERROR, + "A version to be deleted was found but could not be deleted", + )); + } + + tx.commit().await.unwrap(); + + info!("Secret {path} version {latest_version} of {engine_path} engine deleted! {u:?}"); + + Ok(NoContent.into_response()) +} + + +// Not +pub async fn patch_data( + State(pool): State, + Path(kv_path): Path, + Extension(EnginePath(engine_path)): Extension, + Json(secret): Json, +) -> Result { + // TODO: implement only application/merge-patch+json + todo!("Not implemented") +} + diff --git a/src/engines/kv/logic.rs b/src/engines/kv/logic.rs deleted file mode 100644 index 7208759..0000000 --- a/src/engines/kv/logic.rs +++ /dev/null @@ -1,56 +0,0 @@ -use serde_json::Value; - -use super::structs::*; - -// TODO create default function - -#[deprecated(note = "Use Axum functionality with structs instead, also, this should be inlined if it is actually needed")] -/// serialize secret to JSON String -pub fn serialize_secret_json(secret: &KvSecretRes) -> Result { - serde_json::to_string(&secret) -} - -#[deprecated(note = "Use Axum functionality with structs instead, also, this should be inlined if it is actually needed")] -/// deserialize JSON String to secret -pub fn deserialize_secret_struct(raw: &str) -> Result { - serde_json::from_str(raw) -} - -#[deprecated(note = "Use Axum functionality with structs instead, also, this should be inlined if it is actually needed")] -/// serialize metadata to JSON String -pub fn serialize_metadata_json(secret: &SecretMeta) -> Result { - serde_json::to_string(&secret) -} - -#[deprecated(note = "Use Axum functionality with structs instead, also, this should be inlined if it is actually needed")] -/// deserialize JSON String to metadata -pub fn deserialize_metadata_struct(raw: &str) -> Result { - serde_json::from_str(raw) -} - -#[deprecated(note = "Propably not needed (remove deprecation if actually needed)")] -/// Consider: -/// Instead of patching JSON, we should apply the modified fields directly to the database -pub fn patch_metadata( - old: &mut SecretMeta, - new: &SecretMeta, -) -> Result { - let mut patch = serde_json::to_value(old)?; // ? operator is cool: returns early if error was detected - let new_json = serde_json::to_value(new)?; - json_patch::merge(&mut patch, &new_json); - serde_json::from_value(patch) -} - -#[deprecated(note = "DO NOT USE: Use Axum extractors to structs instead")] -#[allow(unreachable_code, unused_variables)] -/// See [JSON extractor documentation](https://docs.rs/axum/latest/axum/struct.Json.html#extractor-example) -pub fn body_to_json(body: String) -> Value { - todo!("REMOVE: Use Axum extractors to structs instead"); - match serde_json::from_str::(body.as_str()) { - Ok(val) => val, - Err(e) => { - log::debug!("Faulty result from conversion: {:?}", e); - "Error converting body".into() - } - } -} diff --git a/src/engines/kv/meta.rs b/src/engines/kv/meta.rs new file mode 100644 index 0000000..caf9844 --- /dev/null +++ b/src/engines/kv/meta.rs @@ -0,0 +1,26 @@ +use crate::storage::DatabaseDriver; +use axum::extract::{Path, State}; + +pub async fn delete_path() -> &'static str { + todo!("not implemented") +} + +pub async fn destroy_path() -> &'static str { + todo!("not implemented") +} + +pub async fn get_meta() -> &'static str { + todo!("not implemented") +} + +pub async fn post_meta( + State(pool): State, + Path((mount_path, kv_path)): Path<(String, String)>, + body: String, +) -> &'static str { + todo!("not implemented") +} + +pub async fn delete_meta() -> &'static str { + todo!("not implemented") +} diff --git a/src/engines/kv/post_secret.sql b/src/engines/kv/post_secret.sql index f10e122..920d7b7 100644 --- a/src/engines/kv/post_secret.sql +++ b/src/engines/kv/post_secret.sql @@ -12,7 +12,7 @@ VALUES ( $4, -- created_time CASE -- Use provided version if given WHEN $5 IS NOT NULL THEN $5 -- version_number (optional) - ELSE COALESCE((SELECT max_version FROM latest_version) + 1, 0) + ELSE COALESCE((SELECT max_version FROM latest_version) + 1, 1) -- otherwise 1 END -- version_number logic ) RETURNING version_number; diff --git a/src/engines/kv/structs.rs b/src/engines/kv/structs.rs index 5eda254..64af36a 100644 --- a/src/engines/kv/structs.rs +++ b/src/engines/kv/structs.rs @@ -1,5 +1,4 @@ use serde::{Deserialize, Serialize}; -use sqlx::FromRow; use std::{collections::HashMap, vec}; use time::{OffsetDateTime, UtcDateTime, serde::rfc3339};