@voxgig/sdkgen 4.20.0 → 4.21.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/voxgig-sdkgen +1 -1
- package/dist/helpers/applicability.js +11 -6
- package/dist/helpers/applicability.js.map +1 -1
- package/dist/helpers/collectDeps.js +31 -6
- package/dist/helpers/collectDeps.js.map +1 -1
- package/dist/helpers/naming.js +2 -2
- package/dist/helpers/naming.js.map +1 -1
- package/dist/tsconfig.tsbuildinfo +1 -1
- package/model/sdkgen.aon +49 -3
- package/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +128 -0
- package/project/.sdk/model/feature/validate.aon +3 -2
- package/project/.sdk/model/target/c.aon +1 -1
- package/project/.sdk/model/target/clojure.aon +1 -1
- package/project/.sdk/model/target/cpp.aon +1 -1
- package/project/.sdk/model/target/csharp.aon +1 -1
- package/project/.sdk/model/target/elixir.aon +1 -1
- package/project/.sdk/model/target/go.aon +1 -1
- package/project/.sdk/model/target/java.aon +1 -1
- package/project/.sdk/model/target/kotlin.aon +1 -1
- package/project/.sdk/model/target/lua.aon +1 -1
- package/project/.sdk/model/target/ocaml.aon +1 -1
- package/project/.sdk/model/target/perl.aon +1 -1
- package/project/.sdk/model/target/php.aon +1 -1
- package/project/.sdk/model/target/py.aon +1 -1
- package/project/.sdk/model/target/rb.aon +1 -1
- package/project/.sdk/model/target/rust.aon +1 -1
- package/project/.sdk/model/target/scala.aon +1 -1
- package/project/.sdk/model/target/swift.aon +1 -1
- package/project/.sdk/model/target/zig.aon +1 -1
- package/project/.sdk/src/cmp/c/Main_c.ts +3 -0
- package/project/.sdk/src/cmp/c/Schema_c.ts +106 -0
- package/project/.sdk/src/cmp/clojure/Main_clojure.ts +2 -0
- package/project/.sdk/src/cmp/clojure/ReadmeExplanation_clojure.ts +1 -0
- package/project/.sdk/src/cmp/clojure/Schema_clojure.ts +73 -0
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +3 -0
- package/project/.sdk/src/cmp/cpp/Schema_cpp.ts +105 -0
- package/project/.sdk/src/cmp/csharp/Main_csharp.ts +3 -0
- package/project/.sdk/src/cmp/csharp/Schema_csharp.ts +85 -0
- package/project/.sdk/src/cmp/elixir/Main_elixir.ts +2 -0
- package/project/.sdk/src/cmp/elixir/ReadmeExplanation_elixir.ts +1 -0
- package/project/.sdk/src/cmp/elixir/Schema_elixir.ts +88 -0
- package/project/.sdk/src/cmp/go/Main_go.ts +2 -0
- package/project/.sdk/src/cmp/go/Schema_go.ts +93 -0
- package/project/.sdk/src/cmp/java/Main_java.ts +2 -0
- package/project/.sdk/src/cmp/java/Schema_java.ts +125 -0
- package/project/.sdk/src/cmp/kotlin/Main_kotlin.ts +2 -0
- package/project/.sdk/src/cmp/kotlin/Schema_kotlin.ts +111 -0
- package/project/.sdk/src/cmp/lua/Main_lua.ts +46 -9
- package/project/.sdk/src/cmp/lua/Package_lua.ts +1 -0
- package/project/.sdk/src/cmp/lua/ReadmeExplanation_lua.ts +1 -0
- package/project/.sdk/src/cmp/lua/Schema_lua.ts +72 -0
- package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +24 -1
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +34 -13
- package/project/.sdk/src/cmp/ocaml/ReadmeExplanation_ocaml.ts +1 -0
- package/project/.sdk/src/cmp/ocaml/Schema_ocaml.ts +99 -0
- package/project/.sdk/src/cmp/perl/Main_perl.ts +2 -0
- package/project/.sdk/src/cmp/perl/ReadmeExplanation_perl.ts +1 -0
- package/project/.sdk/src/cmp/perl/Schema_perl.ts +107 -0
- package/project/.sdk/src/cmp/php/Main_php.ts +2 -0
- package/project/.sdk/src/cmp/php/Package_php.ts +1 -1
- package/project/.sdk/src/cmp/php/ReadmeExplanation_php.ts +1 -0
- package/project/.sdk/src/cmp/php/Schema_php.ts +129 -0
- package/project/.sdk/src/cmp/py/Main_py.ts +2 -0
- package/project/.sdk/src/cmp/py/ReadmeExplanation_py.ts +1 -0
- package/project/.sdk/src/cmp/py/Schema_py.ts +72 -0
- package/project/.sdk/src/cmp/rb/Main_rb.ts +2 -0
- package/project/.sdk/src/cmp/rb/ReadmeExplanation_rb.ts +1 -0
- package/project/.sdk/src/cmp/rb/Schema_rb.ts +70 -0
- package/project/.sdk/src/cmp/rust/Main_rust.ts +3 -0
- package/project/.sdk/src/cmp/rust/Schema_rust.ts +107 -0
- package/project/.sdk/src/cmp/scala/Main_scala.ts +3 -0
- package/project/.sdk/src/cmp/scala/Schema_scala.ts +108 -0
- package/project/.sdk/src/cmp/swift/Main_swift.ts +3 -0
- package/project/.sdk/src/cmp/swift/Schema_swift.ts +92 -0
- package/project/.sdk/src/cmp/zig/Main_zig.ts +3 -0
- package/project/.sdk/src/cmp/zig/Schema_zig.ts +114 -0
- package/project/.sdk/tm/c/core/context.c +3 -0
- package/project/.sdk/tm/c/core/sdk.h +14 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/config.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/config.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/env.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/env.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/export.c +3 -3
- package/project/.sdk/tm/c/feature/secrets/plugin/export.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/host.c +25 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/host.h +3 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/order.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/order.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/point.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/point.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/types.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/types.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/value.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/value.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/version.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugin/version.h +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/aws.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/azuresecrets.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/boru.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/clock.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/doppler.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/encode.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/gcpsecrets.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/hashicorp.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/httpjson.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/infisical.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/minivault.c +2072 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/onepassword.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/proc.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/secretspec.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/sekretoplugins.h +151 -10
- package/project/.sdk/tm/c/feature/secrets/plugins/sha256.c +16 -10
- package/project/.sdk/tm/c/feature/secrets/plugins/sigv4.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/plugins/support.h +12 -8
- package/project/.sdk/tm/c/feature/secrets/plugins/tls.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/sekreto/internal.h +17 -2
- package/project/.sdk/tm/c/feature/secrets/sekreto/json.c +5 -5
- package/project/.sdk/tm/c/feature/secrets/sekreto/providers.c +37 -9
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.c +2 -2
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.h +17 -2
- package/project/.sdk/tm/c/feature/secrets/sekreto/util.c +16 -2
- package/project/.sdk/tm/c/feature/validate.c +364 -0
- package/project/.sdk/tm/c/feature/validate.h +29 -0
- package/project/.sdk/tm/c/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/c/tests/vendor/omni/json.c +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/omni.h +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/runner.c +2 -2
- package/project/.sdk/tm/c/tests/vendor/omni/util.c +2 -2
- package/project/.sdk/tm/c/utility/make_options.c +12 -24
- package/project/.sdk/tm/c/utility/make_spec.c +8 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/capability.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/catalog.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/config.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/depend.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/env.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/export.clj +3 -3
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/graph.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/host.clj +17 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/json.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/order.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/point.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/ref.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/resolve.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/types.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin/version.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/plugin.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/addr.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/chain.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/core.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/json.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/aws.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/azuresecrets.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/boru.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/doppler.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/gcpsecrets.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/hashicorp.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/httpjson.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/infisical.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/minivault.clj +837 -0
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/onepassword.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/proc.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/secretspec.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/plugins/sigv4.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/provider.clj +2 -2
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto/providers.clj +6 -4
- package/project/.sdk/tm/clojure/feature/secrets/voxgig/sekreto.clj +2 -2
- package/project/.sdk/tm/clojure/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/clojure/src/sdk/core.clj +31 -41
- package/project/.sdk/tm/clojure/src/sdk/features.clj +202 -0
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/json.clj +2 -2
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/runner.clj +2 -2
- package/project/.sdk/tm/clojure/test/vendor/omni/voxgig/omni/util.clj +2 -2
- package/project/.sdk/tm/cpp/core/types.hpp +4 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.cpp +3 -3
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.cpp +21 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.hpp +3 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.hpp +9 -7
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Minivault.cpp +1345 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Minivault.hpp +219 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.cpp +22 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.hpp +12 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.cpp +3 -3
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.cpp +2 -2
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.hpp +2 -2
- package/project/.sdk/tm/cpp/feature/validate.hpp +301 -0
- package/project/.sdk/tm/cpp/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/cpp/test/vendor/omni/json.hpp +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/omni.hpp +2 -2
- package/project/.sdk/tm/cpp/test/vendor/omni/util.hpp +2 -2
- package/project/.sdk/tm/cpp/utility/pipeline.hpp +24 -41
- package/project/.sdk/tm/csharp/feature/ValidateFeature.cs +343 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Capability.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Catalog.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Config.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Definition.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Depend.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Entry.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Env.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Export.cs +3 -3
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Graph.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Host.cs +9 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Inst.cs +21 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Json.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Order.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Plugin.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Point.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Refs.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Resolve.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Types.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugin/Version.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Aws.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/AzureSecrets.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Boru.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Child.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Doppler.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/GcpSecrets.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Hashicorp.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/HttpJson.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Infisical.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/MiniVault.cs +1572 -0
- package/project/.sdk/tm/csharp/feature/secrets/plugins/OnePassword.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/SecretSpec.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/plugins/Sigv4.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Json.cs +2 -2
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Providers.cs +3 -2
- package/project/.sdk/tm/csharp/feature/secrets/sekreto/Sekreto.cs +2 -2
- package/project/.sdk/tm/csharp/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/csharp/test/vendor/omni/Runner.cs +2 -2
- package/project/.sdk/tm/csharp/test/vendor/omni/Util.cs +2 -2
- package/project/.sdk/tm/csharp/utility/MakeOptions.cs +12 -85
- package/project/.sdk/tm/csharp/utility/struct/Struct.cs +24 -3
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/capability.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/catalog.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/config.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/depend.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/env.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/error.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/export.ex +7 -4
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/graph.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/host.ex +13 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/inst.ex +15 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/json.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/order.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/point.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/ref.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/resolve.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/types.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/version.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/plugin/voxgig_plugin.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/json.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/aws.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/azuresecrets.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/boru.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/doppler.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/gcpsecrets.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/hashicorp.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/http.ex +3 -3
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/httpjson.ex +3 -3
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/infisical.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/minivault.ex +1033 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/onepassword.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/proc.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/secretspec.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/plugins/sigv4.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/provider.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/providers.ex +17 -5
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets/sekreto/sekreto.ex +2 -2
- package/project/.sdk/tm/elixir/lib/projectname/feature/validate.ex +320 -0
- package/project/.sdk/tm/elixir/lib/projectname/utility.ex +10 -46
- package/project/.sdk/tm/elixir/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/elixir/test/vendor/omni/json.ex +2 -2
- package/project/.sdk/tm/elixir/test/vendor/omni/runner.ex +2 -2
- package/project/.sdk/tm/elixir/test/vendor/omni/util.ex +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugin/capability.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/catalog.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/config.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/depend.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/env.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/export.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugin/graph.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/host.go +25 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/order.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/point.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/ref.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/resolve.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/types.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/util.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugin/version.go +1 -1
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/aws.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/aws/sigv4.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/azuresecrets/azuresecrets.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/boru/boru.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/doppler/doppler.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/gcpsecrets/gcpsecrets.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/hashicorp/hashicorp.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/httpjson/httpjson.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/infisical/infisical.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/minivault/format.go +493 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/minivault/minivault.go +1131 -0
- package/project/.sdk/tm/go/feature/secrets/plugins/onepassword/onepassword.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/plugins/secretspec/secretspec.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/addr.go +2 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/providers.go +14 -2
- package/project/.sdk/tm/go/feature/secrets/sekreto/sekreto.go +2 -2
- package/project/.sdk/tm/go/feature/validate_feature.go +346 -0
- package/project/.sdk/tm/go/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/go/test/omni/omni.go +2 -2
- package/project/.sdk/tm/go/test/omni/util.go +2 -2
- package/project/.sdk/tm/go/utility/make_options.go +13 -54
- package/project/.sdk/tm/go/utility/struct/voxgigstruct.go +24 -8
- package/project/.sdk/tm/java/feature/ValidateFeature.java +330 -0
- package/project/.sdk/tm/java/feature/secrets/plugin/Capability.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Catalog.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Config.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Definition.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Depend.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Entry.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Env.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Export.java +3 -3
- package/project/.sdk/tm/java/feature/secrets/plugin/Graph.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Host.java +3 -3
- package/project/.sdk/tm/java/feature/secrets/plugin/Inst.java +21 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Json.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Order.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Plugin.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/PluginException.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Point.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Refs.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Resolve.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Types.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/plugin/Version.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/Addr.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/Builtins.java +4 -3
- package/project/.sdk/tm/java/feature/secrets/sekreto/Json.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/Provider.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/Sekreto.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/Support.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Aws.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Azuresecrets.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Boru.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Doppler.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Gcpsecrets.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Hashicorp.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Httpjson.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Infisical.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Minivault.java +1448 -0
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Onepassword.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Proc.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Secretspec.java +2 -2
- package/project/.sdk/tm/java/feature/secrets/sekreto/plugins/Sigv4.java +2 -2
- package/project/.sdk/tm/java/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/java/test/vendor/omni/Json.java +2 -2
- package/project/.sdk/tm/java/test/vendor/omni/Runner.java +2 -2
- package/project/.sdk/tm/java/test/vendor/omni/Util.java +2 -2
- package/project/.sdk/tm/java/utility/MakeOptions.java +13 -45
- package/project/.sdk/tm/java/utility/struct/Struct.java +1 -1
- package/project/.sdk/tm/js/src/feature/secrets/plugin/capability.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/catalog.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/config.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/depend.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/env.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/export.js +3 -3
- package/project/.sdk/tm/js/src/feature/secrets/plugin/graph.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/host.js +17 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/index.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/order.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/point.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/ref.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/resolve.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/types.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/plugin/version.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/Sekreto.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/index.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/aws.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/azuresecrets.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/boru.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/doppler.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/gcpsecrets.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/hashicorp.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/httpjson.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/infisical.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/minivault.js +866 -0
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/onepassword.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/secretspec.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/plugins/sigv4.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/addr.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/builtin.js +3 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/dotenv.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/env.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/file.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/memory.js +2 -2
- package/project/.sdk/tm/js/src/feature/secrets/sekreto/provider/support.js +2 -2
- package/project/.sdk/tm/js/src/utility/StructUtility.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/index.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/runner.js +1 -1
- package/project/.sdk/tm/js/test/vendor/omni/util.js +1 -1
- package/project/.sdk/tm/kotlin/feature/ValidateFeature.kt +297 -0
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Capability.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Catalog.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Config.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Depend.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Env.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Export.kt +3 -3
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Graph.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Host.kt +21 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Json.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Order.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Plugin.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Point.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Refs.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Resolve.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Types.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/plugin/Version.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Json.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Provider.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Providers.kt +3 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Sekreto.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Spec.kt +14 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/Support.kt +10 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Aws.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Azuresecrets.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Boru.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Doppler.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Gcpsecrets.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Hashicorp.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Httpjson.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Infisical.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Minivault.kt +1095 -0
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Onepassword.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Secretspec.kt +2 -2
- package/project/.sdk/tm/kotlin/feature/secrets/sekreto/plugins/Sigv4.kt +2 -2
- package/project/.sdk/tm/kotlin/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/kotlin/test/vendor/omni/Json.kt +2 -2
- package/project/.sdk/tm/kotlin/test/vendor/omni/Runner.kt +2 -2
- package/project/.sdk/tm/kotlin/test/vendor/omni/Util.kt +2 -2
- package/project/.sdk/tm/kotlin/utility/MakeOptions.kt +13 -35
- package/project/.sdk/tm/kotlin/utility/MakeSpecUrl.kt +6 -0
- package/project/.sdk/tm/kotlin/utility/struct/Struct.kt +1 -1
- package/project/.sdk/tm/lua/feature/secrets/native/sekretonet.c +2 -2
- package/project/.sdk/tm/lua/feature/secrets/native/sekretovault.c +240 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/capability.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/catalog.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/config.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/depend.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/env.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/export.lua +12 -3
- package/project/.sdk/tm/lua/feature/secrets/plugin/graph.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/host.lua +18 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/json.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/order.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/point.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/ref.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/resolve.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/types.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin/version.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/plugin.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/addr.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/err.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/name.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/aws.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/azuresecrets.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/boru.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/crypto.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/doppler.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/gcpsecrets.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/hashicorp.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/httpjson.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/infisical.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/json.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/minivault.lua +1227 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/net.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/onepassword.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/secretspec.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/sigv4.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/support.lua +2 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto/providers.lua +3 -2
- package/project/.sdk/tm/lua/feature/secrets/sekreto.lua +2 -2
- package/project/.sdk/tm/lua/feature/validate_feature.lua +333 -0
- package/project/.sdk/tm/lua/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/lua/test/vendor/omni/json.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/regex.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/runner.lua +2 -2
- package/project/.sdk/tm/lua/test/vendor/omni/util.lua +2 -2
- package/project/.sdk/tm/lua/utility/make_options.lua +74 -55
- package/project/.sdk/tm/lua/utility/make_spec.lua +8 -1
- package/project/.sdk/tm/lua/utility/struct/regex.lua +1 -1
- package/project/.sdk/tm/lua/utility/struct/struct.lua +1 -1
- package/project/.sdk/tm/ocaml/Makefile +12 -7
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/capability.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/catalog.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/config.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/defs.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/depend.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/env.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/export.ml +5 -3
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/graph.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/host.ml +18 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/order.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/point.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/ref.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/resolve.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/types.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/value.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/version.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/aws.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/azuresecrets.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/boru.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/crypto.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/doppler.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/gcpsecrets.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/hashicorp.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/http.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/httpjson.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/infisical.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/minivault.ml +1086 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/minivault_stubs.c +222 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/onepassword.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/runcmd.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/secretspec.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/sigv4.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls_stubs.c +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/json.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/provider.ml +33 -3
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/secret.ml +2 -2
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/sekreto.ml +4 -3
- package/project/.sdk/tm/ocaml/sdk_features.ml +174 -0
- package/project/.sdk/tm/ocaml/sdk_runtime.ml +12 -37
- package/project/.sdk/tm/ocaml/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/ocaml/test/vendor/omni/omni.ml +2 -2
- package/project/.sdk/tm/perl/core/helpers.pm +64 -16
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Capability.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Catalog.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Config.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Depend.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Env.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Export.pm +3 -3
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Graph.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Host.pm +19 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Order.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Point.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Ref.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Resolve.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Types.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin/Version.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugin/Voxgig/Plugin.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Aws.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Azuresecrets.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Boru.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Doppler.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Gcpsecrets.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Hashicorp.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Httpjson.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Infisical.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Minivault.pm +1380 -0
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Onepassword.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Proc.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Secretspec.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/plugins/Voxgig/Sekreto/Plugins/Sigv4.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto/Addr.pm +2 -2
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto/Providers.pm +4 -3
- package/project/.sdk/tm/perl/feature/secrets/sekreto/Voxgig/Sekreto.pm +2 -2
- package/project/.sdk/tm/perl/feature/validate_feature.pm +319 -0
- package/project/.sdk/tm/perl/lib/Voxgig/Struct.pm +1 -1
- package/project/.sdk/tm/perl/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Runner.pm +1 -1
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni/Util.pm +1 -1
- package/project/.sdk/tm/perl/t/vendor/omni/Voxgig/Omni.pm +1 -1
- package/project/.sdk/tm/perl/utility/make_options.pm +25 -43
- package/project/.sdk/tm/php/feature/ValidateFeature.php +361 -0
- package/project/.sdk/tm/php/feature/secrets/plugin/Capability.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Catalog.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Config.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Depend.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Env.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Export.php +3 -3
- package/project/.sdk/tm/php/feature/secrets/plugin/Graph.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Host.php +26 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Order.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Point.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Ref.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Resolve.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Types.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/Version.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/plugin/plugin.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/aws.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/azuresecrets.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/boru.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/doppler.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/gcpsecrets.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/hashicorp.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/httpjson.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/infisical.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/minivault.php +1250 -0
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/onepassword.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/runcmd.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/secretspec.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/plugins/sigv4.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Addr.php +2 -2
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Providers.php +5 -3
- package/project/.sdk/tm/php/feature/secrets/sekreto/src/Sekreto.php +2 -2
- package/project/.sdk/tm/php/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/php/test/vendor/omni/Runner.php +2 -2
- package/project/.sdk/tm/php/test/vendor/omni/Util.php +2 -2
- package/project/.sdk/tm/php/utility/MakeOptions.php +15 -31
- package/project/.sdk/tm/php/utility/struct/Struct.php +56 -7
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/__init__.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/capability.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/catalog.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/config.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/depend.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/env.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/export.py +2 -2
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/graph.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/host.py +17 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/order.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/point.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/ref.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/resolve.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/types.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_plugin/version.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/__init__.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/addr.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/aws.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/azuresecrets.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/boru.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/doppler.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/hashicorp.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/httpjson.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/infisical.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/minivault.py +1202 -0
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/onepassword.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/secretspec.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/plugins/sigv4.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/providers.py +2 -1
- package/project/.sdk/tm/py/pkg/feature/secrets/voxgig_sekreto/sekreto.py +1 -1
- package/project/.sdk/tm/py/pkg/feature/validate_feature.py +273 -0
- package/project/.sdk/tm/py/pkg/utility/make_options.py +14 -53
- package/project/.sdk/tm/py/pkg/utility/voxgig_struct/voxgig_struct.py +1 -1
- package/project/.sdk/tm/py/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/py/test/voxgig_omni/__init__.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/runner.py +1 -1
- package/project/.sdk/tm/py/test/voxgig_omni/util.py +1 -1
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/capability.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/catalog.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/config.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/depend.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/env.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/export.rb +3 -3
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/graph.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/host.rb +16 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/order.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/point.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/ref.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/resolve.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/types.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin/version.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_plugin.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/addr.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/aws.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/azuresecrets.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/boru.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/doppler.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/gcpsecrets.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/hashicorp.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/httpjson.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/infisical.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/minivault.rb +979 -0
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/onepassword.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/secretspec.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/plugins/sigv4.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/providers.rb +6 -5
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto/sekreto.rb +2 -2
- package/project/.sdk/tm/rb/feature/secrets/voxgig_sekreto.rb +2 -2
- package/project/.sdk/tm/rb/feature/validate_feature.rb +265 -0
- package/project/.sdk/tm/rb/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/rb/test/vendor/omni/runner.rb +2 -2
- package/project/.sdk/tm/rb/test/vendor/omni/util.rb +2 -2
- package/project/.sdk/tm/rb/test/vendor/omni/voxgig_omni.rb +2 -2
- package/project/.sdk/tm/rb/utility/make_options.rb +15 -32
- package/project/.sdk/tm/rb/utility/struct/voxgig_struct.rb +24 -1
- package/project/.sdk/tm/rust/core/mod.rs +3 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/capability.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/catalog.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/config.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/depend.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/env.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/export.rs +3 -3
- package/project/.sdk/tm/rust/feature/secrets/plugin/graph.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/host.rs +24 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/mod.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/order.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/point.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/refs.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/resolve.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/types.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/value.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugin/version.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws/crypto.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws/sigv4.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/aws.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/azuresecrets.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/boru.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/doppler.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/gcpsecrets.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/hashicorp.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson/http.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson/json.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/httpjson.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/infisical.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/minivault/format.rs +425 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/minivault.rs +1076 -0
- package/project/.sdk/tm/rust/feature/secrets/plugins/onepassword.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/plugins/secretspec.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/sekreto/addr.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/sekreto/mod.rs +2 -2
- package/project/.sdk/tm/rust/feature/secrets/sekreto/providers.rs +30 -4
- package/project/.sdk/tm/rust/feature/secrets/sekreto/sekreto.rs +2 -2
- package/project/.sdk/tm/rust/feature/validate.rs +387 -0
- package/project/.sdk/tm/rust/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/rust/tests/vendor/omni/json.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/mod.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/regex.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/runner.rs +2 -2
- package/project/.sdk/tm/rust/tests/vendor/omni/util.rs +2 -2
- package/project/.sdk/tm/rust/utility/make_options.rs +12 -63
- package/project/.sdk/tm/rust/utility/make_spec.rs +10 -3
- package/project/.sdk/tm/scala/feature/ValidateFeature.scala +286 -0
- package/project/.sdk/tm/scala/feature/secrets/plugin/Capability.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Config.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Depend.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Env.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Export.scala +3 -3
- package/project/.sdk/tm/scala/feature/secrets/plugin/Graph.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Host.scala +19 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Json.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Order.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Plugin.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Point.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Refs.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Resolve.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Types.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Value.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/plugin/Version.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Json.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Provider.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Providers.scala +3 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Sekreto.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Spec.scala +13 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/Support.scala +11 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Aws.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Azuresecrets.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Boru.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Doppler.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Gcpsecrets.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Hashicorp.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Httpjson.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Infisical.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Minivault.scala +979 -0
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Onepassword.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Secretspec.scala +2 -2
- package/project/.sdk/tm/scala/feature/secrets/sekreto/plugins/Sigv4.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Json.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Runner.scala +2 -2
- package/project/.sdk/tm/scala/sdktest/vendor/omni/Util.scala +2 -2
- package/project/.sdk/tm/scala/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/scala/utility/Make.scala +12 -41
- package/project/.sdk/tm/scala/utility/MakeSpec.scala +8 -1
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/ValidateFeature.swift +273 -0
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Capability.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Catalog.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Config.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Depend.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Env.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Export.swift +3 -3
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Graph.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Host.swift +17 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Json.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Order.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Point.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Refs.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Resolve.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Types.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Value.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugin/Version.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Aws.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Azuresecrets.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Boru.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Crypto.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Doppler.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Gcpsecrets.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Hashicorp.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Httpjson.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Infisical.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Onepassword.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Proc.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Secretspec.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/plugins/Sigv4.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Addr.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Json.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Provider.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Providers.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/feature/secrets/sekreto/Sekreto.swift +2 -2
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/Make.swift +9 -3
- package/project/.sdk/tm/swift/Sources/ProjectNameSDK/utility/MakeOptions.swift +12 -87
- package/project/.sdk/tm/swift/Tests/ProjectNameSDKTests/PrimaryUtilityTest.swift +3 -3
- package/project/.sdk/tm/swift/Tests/vendor/omni/Json.swift +2 -2
- package/project/.sdk/tm/swift/Tests/vendor/omni/Runner.swift +2 -2
- package/project/.sdk/tm/swift/Tests/vendor/omni/Util.swift +2 -2
- package/project/.sdk/tm/swift/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Capability.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Catalog.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Config.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Depend.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Env.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Export.ts +13 -2
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/FeatureHost.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Graph.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Host.ts +27 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Order.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Point.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Ref.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Resolve.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Types.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/Version.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/plugin/index.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/Sekreto.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/index.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/aws.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/azuresecrets.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/boru.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/doppler.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/gcpsecrets.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/hashicorp.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/httpjson.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/infisical.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/minivault.ts +1034 -0
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/onepassword.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/secretspec.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/plugins/sigv4.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/addr.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/builtin.ts +2 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/dotenv.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/env.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/file.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/memory.ts +1 -1
- package/project/.sdk/tm/ts/src/feature/secrets/sekreto/provider/support.ts +11 -1
- package/project/.sdk/tm/ts/src/utility/StructUtility.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/Runner.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/Util.ts +1 -1
- package/project/.sdk/tm/ts/test/vendor/omni/index.ts +1 -1
- package/project/.sdk/tm/zig/core/utility.zig +20 -44
- package/project/.sdk/tm/zig/feature/secrets/plugin/capability.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/catalog.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/config.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/depend.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/env.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/export.zig +3 -3
- package/project/.sdk/tm/zig/feature/secrets/plugin/graph.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/host.zig +18 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/inst.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/order.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/plugin.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/point.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/ref.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/resolve.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/types.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/value.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugin/version.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/aws.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/azuresecrets.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/boru.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/doppler.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/gcpsecrets.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/hashicorp.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/httpjson.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/infisical.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/minivault.zig +1930 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/onepassword.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/secretspec.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/plugins/sigv4.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/sekreto/addr.zig +2 -2
- package/project/.sdk/tm/zig/feature/secrets/sekreto/builtins.zig +3 -2
- package/project/.sdk/tm/zig/feature/secrets/sekreto/provider.zig +19 -2
- package/project/.sdk/tm/zig/feature/secrets/sekreto/sekreto.zig +2 -2
- package/project/.sdk/tm/zig/feature/validate.zig +293 -0
- package/project/.sdk/tm/zig/src/feature/validate/.gitkeep +0 -0
- package/project/.sdk/tm/zig/test/vendor/omni/omni.zig +2 -2
- package/project/.sdk/tm/zig/test/vendor/omni/regex.zig +2 -2
- package/project/.sdk/tm/zig/utility/voxgigstruct/regex.zig +2 -2
- package/project/.sdk/tm/zig/utility/voxgigstruct/struct.zig +2 -2
- package/project/sdkgen-package.json +1 -1
- package/src/helpers/applicability.ts +11 -6
- package/src/helpers/collectDeps.ts +30 -5
- package/src/helpers/naming.ts +2 -2
|
@@ -0,0 +1,1202 @@
|
|
|
1
|
+
# VENDORED: @voxgig/sekreto 0.2.0 (python/voxgig_sekreto/plugins/minivault.py)
|
|
2
|
+
# Source: https://github.com/voxgig/sekreto @ 108c4a914bee7b6534c30d1c68c25cd1b9377696 [tag: sdk-20260917-1242-0]
|
|
3
|
+
# License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream.
|
|
4
|
+
"""The mini vault: every secret a project owns, encrypted, in one file.
|
|
5
|
+
|
|
6
|
+
A store this library owns outright rather than a client for a server
|
|
7
|
+
somebody else runs. It has a master key and restricted keys, and it is the
|
|
8
|
+
port's worked example of a definition publishing an API beside its
|
|
9
|
+
provider: a chain READS, and writing is a deliberate act with an interface
|
|
10
|
+
of its own.
|
|
11
|
+
|
|
12
|
+
from voxgig_sekreto import Sekreto
|
|
13
|
+
from voxgig_sekreto.plugins.minivault import createvault, minivault, vaultof
|
|
14
|
+
|
|
15
|
+
vault = createvault({'file': 'app.skmv', 'passphrase': MASTER})
|
|
16
|
+
vault.set('api.token', 'tok01')
|
|
17
|
+
vault.grant({'key': 'ci', 'passphrase': CI, 'names': ['api.token']})
|
|
18
|
+
|
|
19
|
+
secrets = Sekreto({
|
|
20
|
+
'plugins': [minivault],
|
|
21
|
+
'providers': [{'kind': 'minivault', 'file': 'app.skmv',
|
|
22
|
+
'vaultkey': 'ci', 'passphrase': CI}],
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
secrets.get('api.token') # the chain reads
|
|
26
|
+
vaultof(secrets).list() # the API writes
|
|
27
|
+
|
|
28
|
+
THE FILE FORMAT IS THE CONTRACT, and the vaults committed under
|
|
29
|
+
test/fixture/ pin it: a vault written by any port is read by every other.
|
|
30
|
+
|
|
31
|
+
magic 4 'SKMV'
|
|
32
|
+
version 1 FORMAT
|
|
33
|
+
kdf 1 1 = PBKDF2-HMAC-SHA256
|
|
34
|
+
cipher 1 1 = AES-256-GCM
|
|
35
|
+
reserved 1 0
|
|
36
|
+
keycount 4 uint32
|
|
37
|
+
per key:
|
|
38
|
+
id 1 + bytes the key id, PLAINTEXT
|
|
39
|
+
salt 1 + bytes
|
|
40
|
+
iters 4 PBKDF2 rounds for this key
|
|
41
|
+
ring 1 + iv, 4 + bytes sealed under the passphrase
|
|
42
|
+
meta 1 + iv, 4 + bytes sealed under the vault's meta key
|
|
43
|
+
entrycount 4 uint32
|
|
44
|
+
per entry:
|
|
45
|
+
id 1 + bytes the blinded lookup id
|
|
46
|
+
name 1 + iv, 4 + bytes sealed under the vault's name key
|
|
47
|
+
value 1 + iv, 4 + bytes sealed under that secret's own key
|
|
48
|
+
|
|
49
|
+
Integers are big-endian and every length precedes its bytes, so the file
|
|
50
|
+
is written with the same two primitives it is read with.
|
|
51
|
+
|
|
52
|
+
NOTHING OUTSIDE A KEY RECORD IS PLAINTEXT. Secret names are sealed, and an
|
|
53
|
+
entry is addressed by a blinded id derived from its own key, so a
|
|
54
|
+
restricted key finds what it was granted without the file ever naming the
|
|
55
|
+
rest. What the file does show anyone is the key ids and how many secrets
|
|
56
|
+
there are.
|
|
57
|
+
|
|
58
|
+
A port of typescript/plugins/minivault.ts, which is canonical.
|
|
59
|
+
"""
|
|
60
|
+
|
|
61
|
+
import ctypes
|
|
62
|
+
import ctypes.util
|
|
63
|
+
import hashlib
|
|
64
|
+
import hmac as hmaclib
|
|
65
|
+
import json
|
|
66
|
+
import os
|
|
67
|
+
import struct
|
|
68
|
+
import sys
|
|
69
|
+
import threading
|
|
70
|
+
|
|
71
|
+
from ...voxgig_plugin import PluginError
|
|
72
|
+
|
|
73
|
+
from ..sekreto import SekretoError, checkname
|
|
74
|
+
from ..providers import ERROR_CODE, PROVIDER_EXPORT, Provider
|
|
75
|
+
|
|
76
|
+
MAGIC = b'SKMV'
|
|
77
|
+
FORMAT = 1
|
|
78
|
+
|
|
79
|
+
KDF_PBKDF2 = 1
|
|
80
|
+
CIPHER_AESGCM = 1
|
|
81
|
+
|
|
82
|
+
# AES-256-GCM: 32-byte keys, 12-byte nonces, 16-byte tags.
|
|
83
|
+
KEYLEN = 32
|
|
84
|
+
IVLEN = 12
|
|
85
|
+
TAGLEN = 16
|
|
86
|
+
SALTLEN = 16
|
|
87
|
+
|
|
88
|
+
#: The PBKDF2-HMAC-SHA256 round count when a caller names none.
|
|
89
|
+
ITERATIONS = 210000
|
|
90
|
+
|
|
91
|
+
#: The key id a vault gets when a caller names none.
|
|
92
|
+
MASTERKEY = 'master'
|
|
93
|
+
|
|
94
|
+
#: The export key the vault API is published under, beside the provider.
|
|
95
|
+
VAULT_EXPORT = 'vault'
|
|
96
|
+
|
|
97
|
+
# Additional authenticated data. Every blob is bound to its PLACE in the
|
|
98
|
+
# file, so no ciphertext can be moved: a restricted key's ring cannot be
|
|
99
|
+
# relabelled as the master's, and one secret's value cannot be served under
|
|
100
|
+
# a name it was never written for.
|
|
101
|
+
AAD_RING = 'skmv1:ring:'
|
|
102
|
+
AAD_META = 'skmv1:meta:'
|
|
103
|
+
AAD_NAME = 'skmv1:name'
|
|
104
|
+
AAD_SECRET = 'skmv1:secret:'
|
|
105
|
+
|
|
106
|
+
# Everything a master reaches is derived from the root key, so rotating is
|
|
107
|
+
# one new random value rather than a re-wrap of each part.
|
|
108
|
+
LABEL_NAMES = 'skmv1:names'
|
|
109
|
+
LABEL_META = 'skmv1:meta'
|
|
110
|
+
LABEL_ID = 'skmv1:id'
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
def _fail(text):
|
|
114
|
+
raise SekretoError('sekreto: minivault: ' + text)
|
|
115
|
+
|
|
116
|
+
|
|
117
|
+
#: The largest key id the format can record.
|
|
118
|
+
#:
|
|
119
|
+
#: A length is written in ONE byte. A longer id wraps that byte and the
|
|
120
|
+
#: writer then appends the whole thing, so every field after it shifts: a
|
|
121
|
+
#: grant with a 300-character id would replace a working vault with an
|
|
122
|
+
#: unreadable one, and say nothing. Checked where an id is ACCEPTED, so the
|
|
123
|
+
#: refusal names the id rather than the file.
|
|
124
|
+
IDMAX = 255
|
|
125
|
+
|
|
126
|
+
|
|
127
|
+
def _checkid(held, what):
|
|
128
|
+
if not held:
|
|
129
|
+
_fail(what)
|
|
130
|
+
if IDMAX < len(held.encode('utf-8')):
|
|
131
|
+
_fail('key id is longer than %d bytes: %s...' % (IDMAX, held[:32]))
|
|
132
|
+
return held
|
|
133
|
+
|
|
134
|
+
|
|
135
|
+
# --- the primitives --------------------------------------------------
|
|
136
|
+
#
|
|
137
|
+
# THREE OF THE FOUR ARE IN THE STANDARD LIBRARY. `hashlib.pbkdf2_hmac`,
|
|
138
|
+
# `hmac` over `hashlib.sha256` and `os.urandom` are all stdlib, so the
|
|
139
|
+
# whole of the binding below exists for the fourth: AES-256-GCM, which
|
|
140
|
+
# python has no interface to at all.
|
|
141
|
+
#
|
|
142
|
+
# IT COMES FROM THE LIBCRYPTO CPYTHON ALREADY LOADS. `import ssl` links
|
|
143
|
+
# OpenSSL into this process - it is what `urllib` speaks HTTPS through, and
|
|
144
|
+
# what the HTTP plugins in this same folder already depend on - so calling
|
|
145
|
+
# its AEAD is the audited-library half of the dependency rule rather than a
|
|
146
|
+
# new package. The alternative was a pure-python AES, which is exactly what
|
|
147
|
+
# the rule exists to forbid: a table-driven cipher passes every
|
|
148
|
+
# known-answer test in the world and still hands its key to anyone who can
|
|
149
|
+
# time a cache.
|
|
150
|
+
#
|
|
151
|
+
# The whole surface is five EVP calls. This module NEVER hand-rolls a
|
|
152
|
+
# primitive and never falls back to one: where libcrypto cannot be found,
|
|
153
|
+
# the vault refuses and says so.
|
|
154
|
+
|
|
155
|
+
_CRYPTO = None
|
|
156
|
+
_CRYPTOLOCK = threading.Lock()
|
|
157
|
+
|
|
158
|
+
_SET_IVLEN = 0x9
|
|
159
|
+
_GET_TAG = 0x10
|
|
160
|
+
_SET_TAG = 0x11
|
|
161
|
+
|
|
162
|
+
|
|
163
|
+
def _libcrypto():
|
|
164
|
+
"""The OpenSSL `ssl` is already using, or a refusal.
|
|
165
|
+
|
|
166
|
+
Looked up in three places because one is not enough anywhere but
|
|
167
|
+
Linux. `find_library` reads the loader's own search path and answers
|
|
168
|
+
for a distribution install; CPython on Windows ships `libcrypto-3.dll`
|
|
169
|
+
beside `_ssl`, and a macOS build from python.org bundles its
|
|
170
|
+
`libcrypto.*.dylib` in the same directory. Importing `ssl` first is
|
|
171
|
+
what makes the second two true: the library is in the process either
|
|
172
|
+
way, and this only has to name the file it came from.
|
|
173
|
+
"""
|
|
174
|
+
global _CRYPTO
|
|
175
|
+
|
|
176
|
+
with _CRYPTOLOCK:
|
|
177
|
+
if None is not _CRYPTO:
|
|
178
|
+
return _CRYPTO
|
|
179
|
+
|
|
180
|
+
import ssl # noqa: F401 (loads libcrypto into this process)
|
|
181
|
+
|
|
182
|
+
tried = []
|
|
183
|
+
|
|
184
|
+
# APPLE'S /usr/lib/libcrypto.dylib IS A TRAP, AND IT MUST NOT BE
|
|
185
|
+
# TRIED. It is a compatibility stub: loading it directly prints
|
|
186
|
+
# "loading libcrypto in an unsafe way" and calls abort(). That is a
|
|
187
|
+
# SIGABRT, not an exception, so the `except OSError: continue`
|
|
188
|
+
# below never runs and the whole process dies — `make test` here
|
|
189
|
+
# ended at `Abort trap: 6` on the first vault case.
|
|
190
|
+
#
|
|
191
|
+
# `find_library('crypto')` returns exactly that path on macOS, so
|
|
192
|
+
# it cannot be the first thing attempted, and on Darwin it cannot
|
|
193
|
+
# be attempted at all. Homebrew's openssl@3 is the real library a
|
|
194
|
+
# mac usually has, and it is named explicitly because it is not on
|
|
195
|
+
# the loader's default search path.
|
|
196
|
+
darwin = 'darwin' == sys.platform
|
|
197
|
+
|
|
198
|
+
found = ctypes.util.find_library('crypto')
|
|
199
|
+
if found and not (darwin and found.startswith('/usr/lib/')):
|
|
200
|
+
tried.append(found)
|
|
201
|
+
|
|
202
|
+
# A statically linked CPython (uv's, python.org's recent builds)
|
|
203
|
+
# has no `_ssl.__file__` at all, so this finds nothing and the list
|
|
204
|
+
# below is the only thing standing between a mac and a refusal.
|
|
205
|
+
try:
|
|
206
|
+
import _ssl
|
|
207
|
+
beside = os.path.dirname(getattr(_ssl, '__file__', '') or '')
|
|
208
|
+
if beside:
|
|
209
|
+
for name in sorted(os.listdir(beside)):
|
|
210
|
+
low = name.lower()
|
|
211
|
+
if low.startswith(('libcrypto', 'crypto')) and (
|
|
212
|
+
low.endswith(('.so', '.dylib', '.dll')) or '.so.' in low
|
|
213
|
+
):
|
|
214
|
+
tried.append(os.path.join(beside, name))
|
|
215
|
+
except Exception:
|
|
216
|
+
pass
|
|
217
|
+
|
|
218
|
+
if darwin:
|
|
219
|
+
# Homebrew on both architectures, then MacPorts. A bare
|
|
220
|
+
# `libcrypto.dylib` is deliberately NOT in this list: the
|
|
221
|
+
# loader would resolve it to /usr/lib and abort.
|
|
222
|
+
tried.extend([
|
|
223
|
+
'/opt/homebrew/opt/openssl@3/lib/libcrypto.dylib',
|
|
224
|
+
'/opt/homebrew/opt/openssl@1.1/lib/libcrypto.dylib',
|
|
225
|
+
'/usr/local/opt/openssl@3/lib/libcrypto.dylib',
|
|
226
|
+
'/usr/local/opt/openssl@1.1/lib/libcrypto.dylib',
|
|
227
|
+
'/opt/local/lib/libcrypto.dylib',
|
|
228
|
+
])
|
|
229
|
+
else:
|
|
230
|
+
tried.extend(['libcrypto.so.3', 'libcrypto.so.1.1', 'libcrypto.so',
|
|
231
|
+
'libcrypto.dylib', 'libcrypto-3-x64.dll',
|
|
232
|
+
'libcrypto-3.dll'])
|
|
233
|
+
|
|
234
|
+
for name in tried:
|
|
235
|
+
try:
|
|
236
|
+
lib = ctypes.CDLL(name)
|
|
237
|
+
if not hasattr(lib, 'EVP_aes_256_gcm'):
|
|
238
|
+
continue
|
|
239
|
+
except OSError:
|
|
240
|
+
continue
|
|
241
|
+
|
|
242
|
+
lib.EVP_CIPHER_CTX_new.restype = ctypes.c_void_p
|
|
243
|
+
lib.EVP_aes_256_gcm.restype = ctypes.c_void_p
|
|
244
|
+
lib.EVP_CIPHER_CTX_free.argtypes = [ctypes.c_void_p]
|
|
245
|
+
|
|
246
|
+
_CRYPTO = lib
|
|
247
|
+
return _CRYPTO
|
|
248
|
+
|
|
249
|
+
_fail('no AES-256-GCM available: this python cannot reach a libcrypto')
|
|
250
|
+
|
|
251
|
+
|
|
252
|
+
def _context():
|
|
253
|
+
made = _libcrypto().EVP_CIPHER_CTX_new()
|
|
254
|
+
if not made:
|
|
255
|
+
_fail('cannot seal')
|
|
256
|
+
return ctypes.c_void_p(made)
|
|
257
|
+
|
|
258
|
+
|
|
259
|
+
def _mac(key, text):
|
|
260
|
+
return hmaclib.new(key, text.encode('utf-8'), hashlib.sha256).digest()
|
|
261
|
+
|
|
262
|
+
|
|
263
|
+
def _kek(passphrase, salt, iters):
|
|
264
|
+
"""The key-encryption key a passphrase unwraps a ring with."""
|
|
265
|
+
if 1 > iters:
|
|
266
|
+
_fail('unusable round count: %d' % iters)
|
|
267
|
+
return hashlib.pbkdf2_hmac('sha256', passphrase.encode('utf-8'), salt, iters, KEYLEN)
|
|
268
|
+
|
|
269
|
+
|
|
270
|
+
def _secretkey(root, name):
|
|
271
|
+
"""The key one named secret's value is encrypted with.
|
|
272
|
+
|
|
273
|
+
DERIVED, never stored, for a master: it holds the root key and so
|
|
274
|
+
reaches every name, including ones written after it was made. A
|
|
275
|
+
restricted key holds the derived keys it was granted and nothing that
|
|
276
|
+
produces another, so every other name is ciphertext to it in exactly
|
|
277
|
+
the way it is to a stranger.
|
|
278
|
+
"""
|
|
279
|
+
return _mac(root, AAD_SECRET + name)
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
def _entryid(key):
|
|
283
|
+
"""Where a secret lives in the file, derived from its own key so that
|
|
284
|
+
finding it needs no plaintext name. One-way: an id yields nothing about
|
|
285
|
+
the key that produced it."""
|
|
286
|
+
return _mac(key, LABEL_ID)
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
def _random(length):
|
|
290
|
+
return os.urandom(length)
|
|
291
|
+
|
|
292
|
+
|
|
293
|
+
def _seal(key, plain, aad):
|
|
294
|
+
"""Ciphertext followed by the 16-byte tag, which is where every other
|
|
295
|
+
port's AEAD leaves it and therefore what the format records."""
|
|
296
|
+
if KEYLEN != len(key):
|
|
297
|
+
_fail('bad key')
|
|
298
|
+
|
|
299
|
+
lib = _libcrypto()
|
|
300
|
+
iv = _random(IVLEN)
|
|
301
|
+
ctx = _context()
|
|
302
|
+
aad = aad.encode('utf-8')
|
|
303
|
+
|
|
304
|
+
try:
|
|
305
|
+
out = ctypes.create_string_buffer(len(plain) + TAGLEN)
|
|
306
|
+
moved = ctypes.c_int()
|
|
307
|
+
|
|
308
|
+
lib.EVP_EncryptInit_ex(ctx, ctypes.c_void_p(lib.EVP_aes_256_gcm()), None, None, None)
|
|
309
|
+
lib.EVP_CIPHER_CTX_ctrl(ctx, _SET_IVLEN, IVLEN, None)
|
|
310
|
+
lib.EVP_EncryptInit_ex(ctx, None, None, key, iv)
|
|
311
|
+
lib.EVP_EncryptUpdate(ctx, None, ctypes.byref(moved), aad, len(aad))
|
|
312
|
+
|
|
313
|
+
if 1 != lib.EVP_EncryptUpdate(ctx, out, ctypes.byref(moved), plain, len(plain)):
|
|
314
|
+
_fail('cannot seal')
|
|
315
|
+
body = out.raw[:moved.value]
|
|
316
|
+
|
|
317
|
+
if 1 != lib.EVP_EncryptFinal_ex(ctx, out, ctypes.byref(moved)):
|
|
318
|
+
_fail('cannot seal')
|
|
319
|
+
body += out.raw[:moved.value]
|
|
320
|
+
|
|
321
|
+
tag = ctypes.create_string_buffer(TAGLEN)
|
|
322
|
+
if 1 != lib.EVP_CIPHER_CTX_ctrl(ctx, _GET_TAG, TAGLEN, tag):
|
|
323
|
+
_fail('cannot seal')
|
|
324
|
+
|
|
325
|
+
return {'iv': iv, 'blob': body + tag.raw[:TAGLEN]}
|
|
326
|
+
finally:
|
|
327
|
+
lib.EVP_CIPHER_CTX_free(ctx)
|
|
328
|
+
|
|
329
|
+
|
|
330
|
+
def _unseal(key, box, aad, what):
|
|
331
|
+
"""The plaintext, or a refusal.
|
|
332
|
+
|
|
333
|
+
A GCM tag that fails to verify is the only evidence there is, and it
|
|
334
|
+
cannot tell a wrong passphrase from a damaged file, so `what` names the
|
|
335
|
+
attempt and the message admits both.
|
|
336
|
+
"""
|
|
337
|
+
if len(box['blob']) < TAGLEN or IVLEN != len(box['iv']):
|
|
338
|
+
_fail(what + ': truncated')
|
|
339
|
+
if KEYLEN != len(key):
|
|
340
|
+
_fail('bad key')
|
|
341
|
+
|
|
342
|
+
lib = _libcrypto()
|
|
343
|
+
body, tag = box['blob'][:-TAGLEN], box['blob'][-TAGLEN:]
|
|
344
|
+
ctx = _context()
|
|
345
|
+
aad = aad.encode('utf-8')
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
out = ctypes.create_string_buffer(len(body) + TAGLEN)
|
|
349
|
+
moved = ctypes.c_int()
|
|
350
|
+
|
|
351
|
+
lib.EVP_DecryptInit_ex(ctx, ctypes.c_void_p(lib.EVP_aes_256_gcm()), None, None, None)
|
|
352
|
+
lib.EVP_CIPHER_CTX_ctrl(ctx, _SET_IVLEN, IVLEN, None)
|
|
353
|
+
lib.EVP_DecryptInit_ex(ctx, None, None, key, box['iv'])
|
|
354
|
+
lib.EVP_DecryptUpdate(ctx, None, ctypes.byref(moved), aad, len(aad))
|
|
355
|
+
|
|
356
|
+
lib.EVP_DecryptUpdate(ctx, out, ctypes.byref(moved), body, len(body))
|
|
357
|
+
plain = out.raw[:moved.value]
|
|
358
|
+
|
|
359
|
+
lib.EVP_CIPHER_CTX_ctrl(ctx, _SET_TAG, TAGLEN, tag)
|
|
360
|
+
if 0 >= lib.EVP_DecryptFinal_ex(ctx, out, ctypes.byref(moved)):
|
|
361
|
+
_fail(what)
|
|
362
|
+
|
|
363
|
+
return plain
|
|
364
|
+
finally:
|
|
365
|
+
lib.EVP_CIPHER_CTX_free(ctx)
|
|
366
|
+
|
|
367
|
+
|
|
368
|
+
def _b64(raw):
|
|
369
|
+
import base64
|
|
370
|
+
return base64.b64encode(raw).decode('ascii')
|
|
371
|
+
|
|
372
|
+
|
|
373
|
+
def _unb64(text, what):
|
|
374
|
+
"""STRICT. A lenient decoder hands back plausible bytes for a corrupted
|
|
375
|
+
payload, and those bytes are then used AS A KEY."""
|
|
376
|
+
import base64
|
|
377
|
+
import binascii
|
|
378
|
+
|
|
379
|
+
try:
|
|
380
|
+
return base64.b64decode(text, validate=True)
|
|
381
|
+
except (binascii.Error, ValueError, TypeError):
|
|
382
|
+
_fail('missing ' + what)
|
|
383
|
+
|
|
384
|
+
|
|
385
|
+
def _dumps(value):
|
|
386
|
+
"""The compact JSON every port writes.
|
|
387
|
+
|
|
388
|
+
SEPARATORS, EXPLICITLY. `json.dumps` puts a space after each comma and
|
|
389
|
+
colon by default, where every other port's encoder writes none - and a
|
|
390
|
+
ring is SEALED, so the difference is not cosmetic: it changes the
|
|
391
|
+
ciphertext length, and a vault written here would be a different size
|
|
392
|
+
from the same vault written anywhere else. The fixtures under
|
|
393
|
+
test/fixture are all the same length, which is what catches this.
|
|
394
|
+
"""
|
|
395
|
+
return json.dumps(value, separators=(',', ':'))
|
|
396
|
+
|
|
397
|
+
|
|
398
|
+
def _jsonof(plain, what):
|
|
399
|
+
try:
|
|
400
|
+
return json.loads(plain.decode('utf-8'))
|
|
401
|
+
except (ValueError, UnicodeDecodeError):
|
|
402
|
+
_fail('unreadable ' + what)
|
|
403
|
+
|
|
404
|
+
|
|
405
|
+
# --- the file --------------------------------------------------------
|
|
406
|
+
|
|
407
|
+
|
|
408
|
+
class _Reader:
|
|
409
|
+
"""A cursor, so that every length check is in one place: a truncated
|
|
410
|
+
vault is refused rather than read as a short one."""
|
|
411
|
+
|
|
412
|
+
def __init__(self, raw):
|
|
413
|
+
self.raw = raw
|
|
414
|
+
self.at = 0
|
|
415
|
+
|
|
416
|
+
def take(self, length):
|
|
417
|
+
"""Reads `length` bytes, or refuses.
|
|
418
|
+
|
|
419
|
+
The bound is checked AGAINST WHAT IS LEFT, never by adding the
|
|
420
|
+
length to the cursor: python's integers cannot wrap, but the check
|
|
421
|
+
reads the same in every port and is the one that is right
|
|
422
|
+
everywhere.
|
|
423
|
+
"""
|
|
424
|
+
if len(self.raw) - self.at < length:
|
|
425
|
+
_fail('the vault file is truncated')
|
|
426
|
+
out = self.raw[self.at:self.at + length]
|
|
427
|
+
self.at += length
|
|
428
|
+
return out
|
|
429
|
+
|
|
430
|
+
def u8(self):
|
|
431
|
+
return self.take(1)[0]
|
|
432
|
+
|
|
433
|
+
def u32(self):
|
|
434
|
+
return struct.unpack('>I', self.take(4))[0]
|
|
435
|
+
|
|
436
|
+
def small(self):
|
|
437
|
+
return self.take(self.u8())
|
|
438
|
+
|
|
439
|
+
def large(self):
|
|
440
|
+
return self.take(self.u32())
|
|
441
|
+
|
|
442
|
+
def sealed(self):
|
|
443
|
+
return {'iv': self.small(), 'blob': self.large()}
|
|
444
|
+
|
|
445
|
+
|
|
446
|
+
def readfile(raw):
|
|
447
|
+
read = _Reader(raw)
|
|
448
|
+
|
|
449
|
+
if MAGIC != read.take(4):
|
|
450
|
+
_fail('not a vault file')
|
|
451
|
+
|
|
452
|
+
version = read.u8()
|
|
453
|
+
if FORMAT != version:
|
|
454
|
+
_fail('unsupported format version: %d' % version)
|
|
455
|
+
|
|
456
|
+
kdf = read.u8()
|
|
457
|
+
cipher = read.u8()
|
|
458
|
+
if KDF_PBKDF2 != kdf or CIPHER_AESGCM != cipher:
|
|
459
|
+
_fail('unsupported kdf or cipher: %d/%d' % (kdf, cipher))
|
|
460
|
+
read.u8()
|
|
461
|
+
|
|
462
|
+
out = {'keys': [], 'entries': []}
|
|
463
|
+
|
|
464
|
+
# A COUNT IS BOUNDED BY WHAT IS LEFT. Each record carries at least a
|
|
465
|
+
# few bytes, so a file claiming four billion of them is damaged; the
|
|
466
|
+
# loop would find that out one truncation at a time, and a caller that
|
|
467
|
+
# preallocated would not.
|
|
468
|
+
keycount = read.u32()
|
|
469
|
+
if len(raw) - read.at < keycount:
|
|
470
|
+
_fail('the vault file is truncated')
|
|
471
|
+
|
|
472
|
+
for _ in range(keycount):
|
|
473
|
+
out['keys'].append({
|
|
474
|
+
'id': read.small().decode('utf-8', 'replace'),
|
|
475
|
+
'salt': read.small(),
|
|
476
|
+
'iters': read.u32(),
|
|
477
|
+
'ring': read.sealed(),
|
|
478
|
+
'meta': read.sealed(),
|
|
479
|
+
})
|
|
480
|
+
|
|
481
|
+
entrycount = read.u32()
|
|
482
|
+
if len(raw) - read.at < entrycount:
|
|
483
|
+
_fail('the vault file is truncated')
|
|
484
|
+
|
|
485
|
+
for _ in range(entrycount):
|
|
486
|
+
out['entries'].append({
|
|
487
|
+
'id': read.small(),
|
|
488
|
+
'name': read.sealed(),
|
|
489
|
+
'value': read.sealed(),
|
|
490
|
+
})
|
|
491
|
+
|
|
492
|
+
if read.at != len(raw):
|
|
493
|
+
_fail('the vault file has trailing bytes')
|
|
494
|
+
|
|
495
|
+
return out
|
|
496
|
+
|
|
497
|
+
|
|
498
|
+
def writefile(vault):
|
|
499
|
+
out = bytearray(MAGIC)
|
|
500
|
+
out.append(FORMAT)
|
|
501
|
+
out.append(KDF_PBKDF2)
|
|
502
|
+
out.append(CIPHER_AESGCM)
|
|
503
|
+
out.append(0)
|
|
504
|
+
|
|
505
|
+
def small(value):
|
|
506
|
+
out.append(len(value))
|
|
507
|
+
out.extend(value)
|
|
508
|
+
|
|
509
|
+
def large(value):
|
|
510
|
+
out.extend(struct.pack('>I', len(value)))
|
|
511
|
+
out.extend(value)
|
|
512
|
+
|
|
513
|
+
def sealed(value):
|
|
514
|
+
small(value['iv'])
|
|
515
|
+
large(value['blob'])
|
|
516
|
+
|
|
517
|
+
out.extend(struct.pack('>I', len(vault['keys'])))
|
|
518
|
+
for record in vault['keys']:
|
|
519
|
+
small(record['id'].encode('utf-8'))
|
|
520
|
+
small(record['salt'])
|
|
521
|
+
out.extend(struct.pack('>I', record['iters']))
|
|
522
|
+
sealed(record['ring'])
|
|
523
|
+
sealed(record['meta'])
|
|
524
|
+
|
|
525
|
+
# SORTED BY ID, which is a blinded value: the file therefore records
|
|
526
|
+
# nothing about the order secrets were written in.
|
|
527
|
+
entries = sorted(vault['entries'], key=lambda record: record['id'])
|
|
528
|
+
|
|
529
|
+
out.extend(struct.pack('>I', len(entries)))
|
|
530
|
+
for record in entries:
|
|
531
|
+
small(record['id'])
|
|
532
|
+
sealed(record['name'])
|
|
533
|
+
sealed(record['value'])
|
|
534
|
+
|
|
535
|
+
return bytes(out)
|
|
536
|
+
|
|
537
|
+
|
|
538
|
+
def _keyrecord(vault, held):
|
|
539
|
+
for record in vault['keys']:
|
|
540
|
+
if held == record['id']:
|
|
541
|
+
return record
|
|
542
|
+
return None
|
|
543
|
+
|
|
544
|
+
|
|
545
|
+
def _entryrecord(vault, held):
|
|
546
|
+
for record in vault['entries']:
|
|
547
|
+
if held == record['id']:
|
|
548
|
+
return record
|
|
549
|
+
return None
|
|
550
|
+
|
|
551
|
+
|
|
552
|
+
def _sameseal(left, right):
|
|
553
|
+
return left['iv'] == right['iv'] and left['blob'] == right['blob']
|
|
554
|
+
|
|
555
|
+
|
|
556
|
+
# --- the file on disk ------------------------------------------------
|
|
557
|
+
|
|
558
|
+
|
|
559
|
+
def _spill(path, raw):
|
|
560
|
+
"""Writes bytes to a path that is not there yet, and REFUSES one that
|
|
561
|
+
is.
|
|
562
|
+
|
|
563
|
+
`O_EXCL` refuses an existing path in ONE syscall and will not follow a
|
|
564
|
+
symlink to make one, and the mode goes on AT CREATION rather than
|
|
565
|
+
after: a chmod once the bytes are written leaves the file readable for
|
|
566
|
+
as long as it takes to write them.
|
|
567
|
+
|
|
568
|
+
Raises OSError. Both callers turn that into a refusal naming the VAULT
|
|
569
|
+
file, which is the path a caller configured - not the temporary this
|
|
570
|
+
one happens to be writing.
|
|
571
|
+
"""
|
|
572
|
+
flags = os.O_WRONLY | os.O_CREAT | os.O_EXCL
|
|
573
|
+
if hasattr(os, 'O_BINARY'):
|
|
574
|
+
flags |= os.O_BINARY
|
|
575
|
+
|
|
576
|
+
with os.fdopen(os.open(path, flags, 0o600), 'wb') as out:
|
|
577
|
+
out.write(raw)
|
|
578
|
+
|
|
579
|
+
|
|
580
|
+
def _putnew(path, made):
|
|
581
|
+
"""Writes a vault file that is not there yet, and REFUSES one that is."""
|
|
582
|
+
try:
|
|
583
|
+
_spill(path, writefile(made))
|
|
584
|
+
except FileExistsError:
|
|
585
|
+
_fail('vault file already exists: ' + path)
|
|
586
|
+
except OSError as err:
|
|
587
|
+
_fail('cannot write ' + path + ': ' + str(err))
|
|
588
|
+
|
|
589
|
+
|
|
590
|
+
def _readmaybe(path):
|
|
591
|
+
try:
|
|
592
|
+
with open(path, 'rb') as held:
|
|
593
|
+
return held.read()
|
|
594
|
+
except FileNotFoundError:
|
|
595
|
+
return None
|
|
596
|
+
except OSError as err:
|
|
597
|
+
_fail('cannot read ' + path + ': ' + str(err))
|
|
598
|
+
|
|
599
|
+
|
|
600
|
+
# --- the lock every handle on one file shares ------------------------
|
|
601
|
+
#
|
|
602
|
+
# Each MiniVault is its own object, so two handles on one path did not
|
|
603
|
+
# coordinate: both could finish `_load` before either saved, and the second
|
|
604
|
+
# rename then discarded the first one's change while reporting success.
|
|
605
|
+
# Keyed by the ABSOLUTE path, so two handles spelled differently still
|
|
606
|
+
# meet.
|
|
607
|
+
#
|
|
608
|
+
# THE GIL DOES NOT MAKE THIS SAFE. It is released around every file read
|
|
609
|
+
# and write, which is exactly where the two handles interleave. A
|
|
610
|
+
# guarantee WITHIN one process, which is what DOCS.md promises and what the
|
|
611
|
+
# go port arranges the same way; two processes still race, and the format's
|
|
612
|
+
# answer to that is the exclusive create and the atomic rename.
|
|
613
|
+
|
|
614
|
+
_LOCKS = {}
|
|
615
|
+
_LOCKSLOCK = threading.Lock()
|
|
616
|
+
|
|
617
|
+
|
|
618
|
+
def _lockfor(path):
|
|
619
|
+
try:
|
|
620
|
+
key = os.path.abspath(path)
|
|
621
|
+
except OSError:
|
|
622
|
+
key = path
|
|
623
|
+
|
|
624
|
+
with _LOCKSLOCK:
|
|
625
|
+
one = _LOCKS.get(key)
|
|
626
|
+
if None is one:
|
|
627
|
+
one = threading.RLock()
|
|
628
|
+
_LOCKS[key] = one
|
|
629
|
+
return one
|
|
630
|
+
|
|
631
|
+
|
|
632
|
+
# --- creating --------------------------------------------------------
|
|
633
|
+
|
|
634
|
+
|
|
635
|
+
def _newvault(keyid, passphrase, iterations):
|
|
636
|
+
"""A new vault: one master key, no secrets."""
|
|
637
|
+
root = _random(KEYLEN)
|
|
638
|
+
salt = _random(SALTLEN)
|
|
639
|
+
|
|
640
|
+
ring = {'v': FORMAT, 'write': True, 'root': _b64(root)}
|
|
641
|
+
meta = {'v': FORMAT, 'master': True, 'write': True, 'grants': []}
|
|
642
|
+
|
|
643
|
+
return {
|
|
644
|
+
'keys': [{
|
|
645
|
+
'id': keyid,
|
|
646
|
+
'salt': salt,
|
|
647
|
+
'iters': iterations,
|
|
648
|
+
'ring': _seal(_kek(passphrase, salt, iterations),
|
|
649
|
+
_dumps(ring).encode('utf-8'), AAD_RING + keyid),
|
|
650
|
+
'meta': _seal(_mac(root, LABEL_META),
|
|
651
|
+
_dumps(meta).encode('utf-8'), AAD_META + keyid),
|
|
652
|
+
}],
|
|
653
|
+
'entries': [],
|
|
654
|
+
}
|
|
655
|
+
|
|
656
|
+
|
|
657
|
+
def _sealkey(root, keyid, passphrase, iters, ring, meta):
|
|
658
|
+
"""One key record: the ring sealed under the passphrase, the metadata
|
|
659
|
+
sealed under the vault's meta key."""
|
|
660
|
+
salt = _random(SALTLEN)
|
|
661
|
+
|
|
662
|
+
return {
|
|
663
|
+
'id': keyid,
|
|
664
|
+
'salt': salt,
|
|
665
|
+
'iters': iters,
|
|
666
|
+
'ring': _seal(_kek(passphrase, salt, iters),
|
|
667
|
+
_dumps(ring).encode('utf-8'), AAD_RING + keyid),
|
|
668
|
+
'meta': _seal(_mac(root, LABEL_META),
|
|
669
|
+
_dumps(meta).encode('utf-8'), AAD_META + keyid),
|
|
670
|
+
}
|
|
671
|
+
|
|
672
|
+
|
|
673
|
+
def _wantkey(held):
|
|
674
|
+
"""AN EMPTY KEY IS NO KEY, so it means `master`.
|
|
675
|
+
|
|
676
|
+
`held or MASTERKEY` would do it, and says less about why: a CLI
|
|
677
|
+
reaches here with SEKRETO_VAULT_KEY set and empty, which is what an
|
|
678
|
+
unset shell variable expands to, and an empty id is not a key anyone
|
|
679
|
+
could have granted.
|
|
680
|
+
"""
|
|
681
|
+
return MASTERKEY if not held else held
|
|
682
|
+
|
|
683
|
+
|
|
684
|
+
def _copyinfo(info):
|
|
685
|
+
"""A detached copy, so that what a caller is handed cannot become what
|
|
686
|
+
this vault believes."""
|
|
687
|
+
return {
|
|
688
|
+
'key': info['key'],
|
|
689
|
+
'master': info['master'],
|
|
690
|
+
'write': info['write'],
|
|
691
|
+
'grants': list(info['grants']),
|
|
692
|
+
}
|
|
693
|
+
|
|
694
|
+
|
|
695
|
+
# --- the vault -------------------------------------------------------
|
|
696
|
+
|
|
697
|
+
|
|
698
|
+
class MiniVault:
|
|
699
|
+
"""A handle on one vault file, opened as ONE key.
|
|
700
|
+
|
|
701
|
+
Every method answers as that key: `list` shows the names it may read,
|
|
702
|
+
`get` answers for those and misses on the rest, and the master-only
|
|
703
|
+
methods refuse for any other key. Nothing is read or derived until the
|
|
704
|
+
first call that needs the file.
|
|
705
|
+
"""
|
|
706
|
+
|
|
707
|
+
def __init__(self, options=None):
|
|
708
|
+
opts = options or {}
|
|
709
|
+
|
|
710
|
+
self._file = opts.get('file')
|
|
711
|
+
self._keyid = _wantkey(opts.get('key'))
|
|
712
|
+
self._passphrase = opts.get('passphrase')
|
|
713
|
+
self._iterations = opts.get('iterations') or ITERATIONS
|
|
714
|
+
self._create = True is opts.get('create')
|
|
715
|
+
|
|
716
|
+
if not isinstance(self._file, str) or not self._file:
|
|
717
|
+
_fail('a vault needs a file')
|
|
718
|
+
if not isinstance(self._passphrase, str) or not self._passphrase:
|
|
719
|
+
_fail('a vault needs a passphrase')
|
|
720
|
+
_checkid(self._keyid, 'a vault needs a key id')
|
|
721
|
+
|
|
722
|
+
self._opened = None
|
|
723
|
+
|
|
724
|
+
@property
|
|
725
|
+
def file(self):
|
|
726
|
+
"""The file this handle reads."""
|
|
727
|
+
return self._file
|
|
728
|
+
|
|
729
|
+
@property
|
|
730
|
+
def key(self):
|
|
731
|
+
"""The key id this handle opens with."""
|
|
732
|
+
return self._keyid
|
|
733
|
+
|
|
734
|
+
def open(self):
|
|
735
|
+
"""Derive the key and read the file NOW rather than at first use."""
|
|
736
|
+
return _copyinfo(self._load()[1]['info'])
|
|
737
|
+
|
|
738
|
+
def close(self):
|
|
739
|
+
"""Forget the derived keys. The next call opens again."""
|
|
740
|
+
self._opened = None
|
|
741
|
+
|
|
742
|
+
def list(self):
|
|
743
|
+
"""The names this key can read, sorted."""
|
|
744
|
+
vault, opened = self._load()
|
|
745
|
+
|
|
746
|
+
if None is not opened['root']:
|
|
747
|
+
namekey = _mac(opened['root'], LABEL_NAMES)
|
|
748
|
+
return sorted(
|
|
749
|
+
_unseal(namekey, record['name'], AAD_NAME,
|
|
750
|
+
'a secret name is damaged').decode('utf-8')
|
|
751
|
+
for record in vault['entries']
|
|
752
|
+
)
|
|
753
|
+
|
|
754
|
+
# A restricted key has no name key, so it reports the grants it can
|
|
755
|
+
# actually find: the vault never tells it what else is in there.
|
|
756
|
+
return sorted(
|
|
757
|
+
name for name in opened['info']['grants']
|
|
758
|
+
if None is not self._findentry(vault, opened['grants'].get(name))
|
|
759
|
+
)
|
|
760
|
+
|
|
761
|
+
def has(self, name):
|
|
762
|
+
return None is not self.get(name)
|
|
763
|
+
|
|
764
|
+
def get(self, name):
|
|
765
|
+
"""The value, or None when the vault does not hold that name or
|
|
766
|
+
this key was not granted it."""
|
|
767
|
+
checkname(name)
|
|
768
|
+
vault, opened = self._load()
|
|
769
|
+
|
|
770
|
+
key = self._keyfor(opened, name)
|
|
771
|
+
# OUTSIDE THE GRANT IS A MISS, deliberately. The vault answers as
|
|
772
|
+
# the key that opened it, so a name this key cannot read is a name
|
|
773
|
+
# this store does not hold for this caller.
|
|
774
|
+
if None is key:
|
|
775
|
+
return None
|
|
776
|
+
|
|
777
|
+
entry = self._findentry(vault, key)
|
|
778
|
+
if None is entry:
|
|
779
|
+
return None
|
|
780
|
+
|
|
781
|
+
return _unseal(key, entry['value'], AAD_SECRET + name,
|
|
782
|
+
'the value of ' + name + ' is damaged').decode('utf-8')
|
|
783
|
+
|
|
784
|
+
def set(self, name, value):
|
|
785
|
+
"""Write a value. A master writes any name; a restricted key
|
|
786
|
+
holding `write` overwrites the names it was granted, and creates
|
|
787
|
+
none."""
|
|
788
|
+
# Every write on this file, from any handle in this process,
|
|
789
|
+
# serializes here; see _lockfor.
|
|
790
|
+
with _lockfor(self._file):
|
|
791
|
+
checkname(name)
|
|
792
|
+
if not isinstance(value, str):
|
|
793
|
+
_fail('a secret value must be text: ' + name)
|
|
794
|
+
|
|
795
|
+
vault, opened = self._load()
|
|
796
|
+
|
|
797
|
+
if not opened['info']['write']:
|
|
798
|
+
_fail('key ' + opened['info']['key'] + ' is read-only')
|
|
799
|
+
|
|
800
|
+
key = self._keyfor(opened, name)
|
|
801
|
+
if None is key:
|
|
802
|
+
_fail('key ' + opened['info']['key'] + ' was not granted ' + name)
|
|
803
|
+
|
|
804
|
+
sealedvalue = _seal(key, value.encode('utf-8'), AAD_SECRET + name)
|
|
805
|
+
entry = _entryrecord(vault, _entryid(key))
|
|
806
|
+
|
|
807
|
+
if None is not entry:
|
|
808
|
+
entry['value'] = sealedvalue
|
|
809
|
+
else:
|
|
810
|
+
# A NEW NAME NEEDS THE NAME KEY, which only a master holds.
|
|
811
|
+
# So a restricted key with `write` updates what it was
|
|
812
|
+
# granted and cannot grow the vault.
|
|
813
|
+
root = self._rootof(opened, 'creating the secret ' + name)
|
|
814
|
+
vault['entries'].append({
|
|
815
|
+
'id': _entryid(key),
|
|
816
|
+
'name': _seal(_mac(root, LABEL_NAMES),
|
|
817
|
+
name.encode('utf-8'), AAD_NAME),
|
|
818
|
+
'value': sealedvalue,
|
|
819
|
+
})
|
|
820
|
+
|
|
821
|
+
self._save(vault)
|
|
822
|
+
|
|
823
|
+
def remove(self, name):
|
|
824
|
+
"""Drop a name. Master only."""
|
|
825
|
+
# Every write on this file, from any handle in this process,
|
|
826
|
+
# serializes here; see _lockfor.
|
|
827
|
+
with _lockfor(self._file):
|
|
828
|
+
checkname(name)
|
|
829
|
+
vault, opened = self._load()
|
|
830
|
+
root = self._rootof(opened, 'removing a secret')
|
|
831
|
+
|
|
832
|
+
wanted = _entryid(_secretkey(root, name))
|
|
833
|
+
entry = _entryrecord(vault, wanted)
|
|
834
|
+
if None is entry:
|
|
835
|
+
_fail('no such secret: ' + name)
|
|
836
|
+
|
|
837
|
+
vault['entries'] = [one for one in vault['entries'] if wanted != one['id']]
|
|
838
|
+
self._save(vault)
|
|
839
|
+
|
|
840
|
+
def keys(self):
|
|
841
|
+
"""Every key in the file, with what it may do. Master only."""
|
|
842
|
+
vault, opened = self._load()
|
|
843
|
+
self._rootof(opened, 'listing the keys')
|
|
844
|
+
|
|
845
|
+
out = []
|
|
846
|
+
for record in vault['keys']:
|
|
847
|
+
meta = self._metaof(opened, record)
|
|
848
|
+
if None is meta:
|
|
849
|
+
out.append({'key': record['id'], 'master': False,
|
|
850
|
+
'write': False, 'grants': []})
|
|
851
|
+
else:
|
|
852
|
+
out.append({
|
|
853
|
+
'key': record['id'],
|
|
854
|
+
'master': True is meta.get('master'),
|
|
855
|
+
'write': True is meta.get('write'),
|
|
856
|
+
'grants': sorted(meta.get('grants') or []),
|
|
857
|
+
})
|
|
858
|
+
return out
|
|
859
|
+
|
|
860
|
+
def grant(self, spec=None):
|
|
861
|
+
"""Mint a restricted key. Master only."""
|
|
862
|
+
# Every write on this file, from any handle in this process,
|
|
863
|
+
# serializes here; see _lockfor.
|
|
864
|
+
with _lockfor(self._file):
|
|
865
|
+
vault, opened = self._load()
|
|
866
|
+
root = self._rootof(opened, 'granting a key')
|
|
867
|
+
|
|
868
|
+
spec = spec or {}
|
|
869
|
+
_checkid(spec.get('key'), 'a grant needs a key id')
|
|
870
|
+
if not isinstance(spec.get('passphrase'), str) or not spec['passphrase']:
|
|
871
|
+
_fail('a grant needs a passphrase')
|
|
872
|
+
if None is not _keyrecord(vault, spec['key']):
|
|
873
|
+
_fail('key already exists: ' + spec['key'])
|
|
874
|
+
|
|
875
|
+
names = sorted(spec.get('names') or [])
|
|
876
|
+
grants = {}
|
|
877
|
+
for name in names:
|
|
878
|
+
checkname(name)
|
|
879
|
+
grants[name] = _b64(_secretkey(root, name))
|
|
880
|
+
|
|
881
|
+
write = True is spec.get('write')
|
|
882
|
+
vault['keys'].append(_sealkey(
|
|
883
|
+
root, spec['key'], spec['passphrase'],
|
|
884
|
+
spec.get('iterations') or self._iterations,
|
|
885
|
+
# GRANTS IS ALWAYS THERE, even granted nothing. A ring
|
|
886
|
+
# without it is a MASTER's ring in every port's reader, so
|
|
887
|
+
# dropping the empty map would be a key that reads the
|
|
888
|
+
# whole vault.
|
|
889
|
+
{'v': FORMAT, 'write': write, 'grants': grants},
|
|
890
|
+
{'v': FORMAT, 'master': False, 'write': write, 'grants': names}))
|
|
891
|
+
|
|
892
|
+
self._save(vault)
|
|
893
|
+
|
|
894
|
+
def revoke(self, key):
|
|
895
|
+
"""Drop a key. Master only.
|
|
896
|
+
|
|
897
|
+
Anyone who already copied the file keeps whatever that key could
|
|
898
|
+
read, so revoking bars future reads of the LIVE file and `rotate`
|
|
899
|
+
is what takes a secret back.
|
|
900
|
+
"""
|
|
901
|
+
# Every write on this file, from any handle in this process,
|
|
902
|
+
# serializes here; see _lockfor.
|
|
903
|
+
with _lockfor(self._file):
|
|
904
|
+
vault, opened = self._load()
|
|
905
|
+
self._rootof(opened, 'revoking a key')
|
|
906
|
+
|
|
907
|
+
if key == opened['info']['key']:
|
|
908
|
+
_fail('a key cannot revoke itself: ' + key)
|
|
909
|
+
if None is _keyrecord(vault, key):
|
|
910
|
+
_fail('no such key: ' + key)
|
|
911
|
+
|
|
912
|
+
vault['keys'] = [one for one in vault['keys'] if key != one['id']]
|
|
913
|
+
self._save(vault)
|
|
914
|
+
|
|
915
|
+
def rotate(self):
|
|
916
|
+
"""A new root key, every value re-encrypted under it, and EVERY
|
|
917
|
+
OTHER KEY DROPPED. Master only.
|
|
918
|
+
|
|
919
|
+
The other keys go because they must: their rings are sealed under
|
|
920
|
+
passphrases this process does not have. Re-grant afterwards.
|
|
921
|
+
"""
|
|
922
|
+
# Every write on this file, from any handle in this process,
|
|
923
|
+
# serializes here; see _lockfor.
|
|
924
|
+
with _lockfor(self._file):
|
|
925
|
+
vault, opened = self._load()
|
|
926
|
+
self._rootof(opened, 'rotating the vault')
|
|
927
|
+
|
|
928
|
+
# Read everything out under the old root before anything
|
|
929
|
+
# changes: once the root is replaced the old derived keys are
|
|
930
|
+
# unreachable.
|
|
931
|
+
plain = [(name, self.get(name)) for name in self.list()]
|
|
932
|
+
|
|
933
|
+
root = _random(KEYLEN)
|
|
934
|
+
namekey = _mac(root, LABEL_NAMES)
|
|
935
|
+
|
|
936
|
+
entries = []
|
|
937
|
+
for name, value in plain:
|
|
938
|
+
key = _secretkey(root, name)
|
|
939
|
+
entries.append({
|
|
940
|
+
'id': _entryid(key),
|
|
941
|
+
'name': _seal(namekey, name.encode('utf-8'), AAD_NAME),
|
|
942
|
+
'value': _seal(key, value.encode('utf-8'), AAD_SECRET + name),
|
|
943
|
+
})
|
|
944
|
+
|
|
945
|
+
record = _keyrecord(vault, self._keyid)
|
|
946
|
+
fresh = _sealkey(root, self._keyid, self._passphrase, record['iters'],
|
|
947
|
+
{'v': FORMAT, 'write': True, 'root': _b64(root)},
|
|
948
|
+
{'v': FORMAT, 'master': True, 'write': True, 'grants': []})
|
|
949
|
+
|
|
950
|
+
# SAVE FIRST, adopt second. A handle holding the new root over
|
|
951
|
+
# a file that still holds the old one reads nothing and says
|
|
952
|
+
# the vault is damaged, which is the wrong story about a failed
|
|
953
|
+
# write.
|
|
954
|
+
self._save({'keys': [fresh], 'entries': entries})
|
|
955
|
+
|
|
956
|
+
self._opened = {
|
|
957
|
+
'info': {'key': self._keyid, 'master': True, 'write': True, 'grants': []},
|
|
958
|
+
'root': root,
|
|
959
|
+
'grants': {},
|
|
960
|
+
'ring': fresh['ring'],
|
|
961
|
+
}
|
|
962
|
+
|
|
963
|
+
# --- inside ------------------------------------------------------
|
|
964
|
+
|
|
965
|
+
def _bytes(self):
|
|
966
|
+
raw = _readmaybe(self._file)
|
|
967
|
+
if None is not raw:
|
|
968
|
+
return raw
|
|
969
|
+
|
|
970
|
+
# A vault is configured deliberately, with a key. Its absence is a
|
|
971
|
+
# broken deployment and never "no secrets here": answering a miss
|
|
972
|
+
# would send the chain on to a weaker store.
|
|
973
|
+
if not self._create:
|
|
974
|
+
_fail('no vault file: ' + self._file)
|
|
975
|
+
|
|
976
|
+
_putnew(self._file, _newvault(self._keyid, self._passphrase, self._iterations))
|
|
977
|
+
|
|
978
|
+
raw = _readmaybe(self._file)
|
|
979
|
+
if None is raw:
|
|
980
|
+
_fail('cannot read ' + self._file)
|
|
981
|
+
return raw
|
|
982
|
+
|
|
983
|
+
def _load(self):
|
|
984
|
+
vault = readfile(self._bytes())
|
|
985
|
+
record = _keyrecord(vault, self._keyid)
|
|
986
|
+
|
|
987
|
+
if None is record:
|
|
988
|
+
# REVOKED, or never there. Either way this handle is finished,
|
|
989
|
+
# and dropping what it derived is what stops the next call
|
|
990
|
+
# answering from memory.
|
|
991
|
+
self._opened = None
|
|
992
|
+
_fail('no such key: ' + self._keyid)
|
|
993
|
+
|
|
994
|
+
# The file still holds this key, and holds the SAME ring: a key
|
|
995
|
+
# revoked and re-granted under another passphrase is a different
|
|
996
|
+
# key wearing the id, and re-deriving is what refuses it.
|
|
997
|
+
if None is not self._opened and _sameseal(self._opened['ring'], record['ring']):
|
|
998
|
+
return vault, self._opened
|
|
999
|
+
|
|
1000
|
+
self._opened = None
|
|
1001
|
+
|
|
1002
|
+
plain = _unseal(
|
|
1003
|
+
_kek(self._passphrase, record['salt'], record['iters']),
|
|
1004
|
+
record['ring'], AAD_RING + self._keyid,
|
|
1005
|
+
'wrong passphrase for key ' + self._keyid + ', or a damaged vault')
|
|
1006
|
+
|
|
1007
|
+
ring = _jsonof(plain, 'key ring for ' + self._keyid)
|
|
1008
|
+
|
|
1009
|
+
grants = {}
|
|
1010
|
+
for name, key in (ring.get('grants') or {}).items():
|
|
1011
|
+
grants[name] = _unb64(key, 'a granted key')
|
|
1012
|
+
|
|
1013
|
+
root = ring.get('root')
|
|
1014
|
+
self._opened = {
|
|
1015
|
+
'info': {
|
|
1016
|
+
'key': self._keyid,
|
|
1017
|
+
'master': None is not root,
|
|
1018
|
+
'write': None is not root or True is ring.get('write'),
|
|
1019
|
+
'grants': sorted(grants.keys()),
|
|
1020
|
+
},
|
|
1021
|
+
'root': None if None is root else _unb64(root, 'the root key'),
|
|
1022
|
+
'grants': grants,
|
|
1023
|
+
'ring': record['ring'],
|
|
1024
|
+
}
|
|
1025
|
+
|
|
1026
|
+
return vault, self._opened
|
|
1027
|
+
|
|
1028
|
+
def _rootof(self, opened, what):
|
|
1029
|
+
if None is opened['root']:
|
|
1030
|
+
_fail(what + ' needs a master key, and ' + opened['info']['key'] +
|
|
1031
|
+
' is restricted')
|
|
1032
|
+
return opened['root']
|
|
1033
|
+
|
|
1034
|
+
def _keyfor(self, opened, name):
|
|
1035
|
+
"""The key for one name, or None when this key cannot reach it."""
|
|
1036
|
+
if None is not opened['root']:
|
|
1037
|
+
return _secretkey(opened['root'], name)
|
|
1038
|
+
return opened['grants'].get(name)
|
|
1039
|
+
|
|
1040
|
+
def _findentry(self, vault, key):
|
|
1041
|
+
if None is key:
|
|
1042
|
+
return None
|
|
1043
|
+
return _entryrecord(vault, _entryid(key))
|
|
1044
|
+
|
|
1045
|
+
def _metaof(self, opened, record):
|
|
1046
|
+
root = self._rootof(opened, 'reading key metadata')
|
|
1047
|
+
what = 'metadata for key ' + record['id']
|
|
1048
|
+
|
|
1049
|
+
try:
|
|
1050
|
+
return _jsonof(
|
|
1051
|
+
_unseal(_mac(root, LABEL_META), record['meta'],
|
|
1052
|
+
AAD_META + record['id'], what),
|
|
1053
|
+
what)
|
|
1054
|
+
except SekretoError:
|
|
1055
|
+
# A record written under a root key this one has replaced. The
|
|
1056
|
+
# key is still in the file and still opens with its own
|
|
1057
|
+
# passphrase, so it is reported rather than hidden - with what
|
|
1058
|
+
# it can do unknown.
|
|
1059
|
+
return None
|
|
1060
|
+
|
|
1061
|
+
def _save(self, vault):
|
|
1062
|
+
"""Read, change, and REPLACE - never edit in place.
|
|
1063
|
+
|
|
1064
|
+
THE TEMPORARY IS RANDOM AND EXCLUSIVE. `<vault>.<pid>.tmp` is a
|
|
1065
|
+
name anyone can predict, so anyone who can write the vault's
|
|
1066
|
+
directory could put a symlink there and have the next save
|
|
1067
|
+
truncate whatever it pointed at.
|
|
1068
|
+
"""
|
|
1069
|
+
temp = self._file + '.' + _random(8).hex() + '.tmp'
|
|
1070
|
+
|
|
1071
|
+
try:
|
|
1072
|
+
_spill(temp, writefile(vault))
|
|
1073
|
+
os.replace(temp, self._file)
|
|
1074
|
+
except OSError as err:
|
|
1075
|
+
try:
|
|
1076
|
+
os.unlink(temp)
|
|
1077
|
+
except OSError:
|
|
1078
|
+
# The vault is unchanged either way, and the write error is
|
|
1079
|
+
# what the caller needs to be told about.
|
|
1080
|
+
pass
|
|
1081
|
+
_fail('cannot write ' + self._file + ': ' + str(err))
|
|
1082
|
+
|
|
1083
|
+
|
|
1084
|
+
def openvault(options):
|
|
1085
|
+
"""Open a vault file as one key.
|
|
1086
|
+
|
|
1087
|
+
The handle is lazy. Nothing is read, and no passphrase is stretched,
|
|
1088
|
+
until a method needs the file.
|
|
1089
|
+
"""
|
|
1090
|
+
return MiniVault(options)
|
|
1091
|
+
|
|
1092
|
+
|
|
1093
|
+
def createvault(options):
|
|
1094
|
+
"""Make a vault file and return a handle on its master key.
|
|
1095
|
+
|
|
1096
|
+
Refuses a file that is already there: a vault is created once, and
|
|
1097
|
+
overwriting one discards every secret in it.
|
|
1098
|
+
"""
|
|
1099
|
+
opts = options or {}
|
|
1100
|
+
|
|
1101
|
+
file = opts.get('file')
|
|
1102
|
+
passphrase = opts.get('passphrase')
|
|
1103
|
+
|
|
1104
|
+
if not isinstance(file, str) or not file:
|
|
1105
|
+
_fail('a vault needs a file')
|
|
1106
|
+
if not isinstance(passphrase, str) or not passphrase:
|
|
1107
|
+
_fail('a vault needs a passphrase')
|
|
1108
|
+
|
|
1109
|
+
keyid = _checkid(_wantkey(opts.get('key')), 'a vault needs a key id')
|
|
1110
|
+
|
|
1111
|
+
# No existence check first: the check and the write would be two steps,
|
|
1112
|
+
# and `_putnew` refuses an existing file in ONE.
|
|
1113
|
+
_putnew(file, _newvault(keyid, passphrase, opts.get('iterations') or ITERATIONS))
|
|
1114
|
+
|
|
1115
|
+
return openvault(opts)
|
|
1116
|
+
|
|
1117
|
+
|
|
1118
|
+
# --- the provider ----------------------------------------------------
|
|
1119
|
+
|
|
1120
|
+
|
|
1121
|
+
class MiniVaultProvider(Provider):
|
|
1122
|
+
"""Read a vault as one store in a chain.
|
|
1123
|
+
|
|
1124
|
+
The provider is the READ half and nothing more: a chain resolves
|
|
1125
|
+
secrets, and writing one is a deliberate act with an API of its own.
|
|
1126
|
+
"""
|
|
1127
|
+
|
|
1128
|
+
def __init__(self, vault):
|
|
1129
|
+
self.vault = vault
|
|
1130
|
+
|
|
1131
|
+
def lookup(self, name):
|
|
1132
|
+
return self.vault.get(name)
|
|
1133
|
+
|
|
1134
|
+
def describe(self):
|
|
1135
|
+
return 'minivault:' + self.vault.file
|
|
1136
|
+
|
|
1137
|
+
|
|
1138
|
+
def minivaultprovider(options):
|
|
1139
|
+
"""A vault provider from options, for a chain built by hand."""
|
|
1140
|
+
return MiniVaultProvider(openvault(options))
|
|
1141
|
+
|
|
1142
|
+
|
|
1143
|
+
def minivaultoptions(spec):
|
|
1144
|
+
"""The vault options a provider spec describes."""
|
|
1145
|
+
return {
|
|
1146
|
+
'file': spec.get('file') or '',
|
|
1147
|
+
'key': spec.get('vaultkey'),
|
|
1148
|
+
'passphrase': spec.get('passphrase') or '',
|
|
1149
|
+
'iterations': spec.get('iterations'),
|
|
1150
|
+
'create': True is spec.get('create'),
|
|
1151
|
+
}
|
|
1152
|
+
|
|
1153
|
+
|
|
1154
|
+
def vaultof(secrets, store=None):
|
|
1155
|
+
"""The vault behind a store in a chain, as its programmatic API.
|
|
1156
|
+
|
|
1157
|
+
With no store named, the unqualified alias answers: one vault in the
|
|
1158
|
+
chain resolves whatever it is called, and two raise rather than
|
|
1159
|
+
picking one.
|
|
1160
|
+
"""
|
|
1161
|
+
if None is store:
|
|
1162
|
+
found = secrets.host.exports('minivault/' + VAULT_EXPORT)
|
|
1163
|
+
if None is found:
|
|
1164
|
+
_fail('no minivault store in this chain')
|
|
1165
|
+
return found
|
|
1166
|
+
|
|
1167
|
+
# A NAMED STORE MUST EXIST, and the alias must not stand in for it.
|
|
1168
|
+
# `host.exports` falls back to the alias when the exact ref misses, so
|
|
1169
|
+
# asking for `minivault` in a chain whose only vault is named `app`
|
|
1170
|
+
# used to hand back the `app` vault - and then write to it. Naming a
|
|
1171
|
+
# store that is not there raises, which is the rule the whole library
|
|
1172
|
+
# follows: `try` already means "may not have it", so it cannot also
|
|
1173
|
+
# mean "may not exist".
|
|
1174
|
+
ref = 'minivault' if 'minivault' == store else 'minivault$' + store
|
|
1175
|
+
|
|
1176
|
+
if None is secrets.host.instance(ref):
|
|
1177
|
+
_fail('no minivault store named ' + store + ' in this chain')
|
|
1178
|
+
|
|
1179
|
+
return secrets.host.exports(ref + '/' + VAULT_EXPORT)
|
|
1180
|
+
|
|
1181
|
+
|
|
1182
|
+
def _define(inst):
|
|
1183
|
+
options = minivaultoptions(inst.options or {})
|
|
1184
|
+
|
|
1185
|
+
try:
|
|
1186
|
+
# `openvault` refuses bad configuration HERE, so a mistyped chain
|
|
1187
|
+
# fails at construction. Reaching the FILE is not configuration:
|
|
1188
|
+
# the handle is lazy.
|
|
1189
|
+
vault = openvault(options)
|
|
1190
|
+
except SekretoError as err:
|
|
1191
|
+
raise PluginError(ERROR_CODE, str(err), {'ref': inst.ref, 'cause': str(err)})
|
|
1192
|
+
|
|
1193
|
+
inst.export(PROVIDER_EXPORT, MiniVaultProvider(vault))
|
|
1194
|
+
inst.export(VAULT_EXPORT, vault)
|
|
1195
|
+
|
|
1196
|
+
|
|
1197
|
+
# The plugin: the `minivault` provider kind, as a voxgig/plugin definition.
|
|
1198
|
+
#
|
|
1199
|
+
# Written out rather than built by `providerplugin`, because this
|
|
1200
|
+
# definition publishes TWO exports: `provider`, the read half every kind
|
|
1201
|
+
# publishes, and `vault`, the programmatic API.
|
|
1202
|
+
minivault = {'name': 'minivault', 'define': _define}
|