@voxgig/sdkgen 4.10.0 → 4.11.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/package.json +1 -1
- package/project/.sdk/model/feature/secrets.aon +330 -0
- package/project/.sdk/model/target/c.aon +15 -2
- package/project/.sdk/model/target/cpp.aon +18 -0
- package/project/.sdk/model/target/lua.aon +17 -0
- package/project/.sdk/model/target/ocaml.aon +48 -5
- package/project/.sdk/model/target/zig.aon +30 -4
- package/project/.sdk/src/cmp/c/Config_c.ts +338 -1
- package/project/.sdk/src/cmp/c/Main_c.ts +57 -2
- package/project/.sdk/src/cmp/c/Package_c.ts +12 -2
- package/project/.sdk/src/cmp/cpp/Config_cpp.ts +324 -2
- package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +2 -0
- package/project/.sdk/src/cmp/cpp/Main_cpp.ts +62 -4
- package/project/.sdk/src/cmp/cpp/Package_cpp.ts +10 -0
- package/project/.sdk/src/cmp/lua/Config_lua.ts +88 -0
- package/project/.sdk/src/cmp/lua/Gitignore_lua.ts +4 -0
- package/project/.sdk/src/cmp/lua/Main_lua.ts +93 -3
- package/project/.sdk/src/cmp/lua/Package_lua.ts +60 -0
- package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +10 -0
- package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +183 -5
- package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +160 -3
- package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +25 -1
- package/project/.sdk/src/cmp/zig/Config_zig.ts +130 -9
- package/project/.sdk/src/cmp/zig/Main_zig.ts +208 -4
- package/project/.sdk/{tm/zig/build.zig → src/cmp/zig/fragment/Build.fragment.zig} +7 -0
- package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +25 -0
- package/project/.sdk/{tm/zig/root.zig → src/cmp/zig/fragment/Root.fragment.zig} +9 -0
- package/project/.sdk/tm/c/Makefile +58 -9
- package/project/.sdk/tm/c/core/sdk.h +10 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.c +133 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/capability.h +39 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.c +83 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/catalog.h +48 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/config.c +413 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/config.h +24 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.c +264 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/depend.h +29 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/env.c +220 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/env.h +19 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/export.c +97 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/export.h +19 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.c +237 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/graph.h +17 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/host.c +1494 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/host.h +135 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/order.c +288 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/order.h +18 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/point.c +141 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/point.h +80 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.c +170 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/ref.h +52 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.c +98 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/resolve.h +18 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/types.c +150 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/types.h +104 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/value.c +649 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/value.h +135 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/version.c +151 -0
- package/project/.sdk/tm/c/feature/secrets/plugin/version.h +34 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/aws.c +281 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/azuresecrets.c +207 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/boru.c +164 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/clock.c +75 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/doppler.c +141 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/encode.c +144 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/gcpsecrets.c +177 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/hashicorp.c +239 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/httpjson.c +599 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/infisical.c +165 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/onepassword.c +194 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/proc.c +233 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/secretspec.c +125 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sekretoplugins.h +125 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sha256.c +270 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/sigv4.c +382 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/support.h +153 -0
- package/project/.sdk/tm/c/feature/secrets/plugins/tls.c +420 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/internal.h +86 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/json.c +721 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/providers.c +813 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.c +944 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.h +490 -0
- package/project/.sdk/tm/c/feature/secrets/sekreto/util.c +442 -0
- package/project/.sdk/tm/c/feature/secrets.c +797 -0
- package/project/.sdk/tm/c/feature/secrets.h +46 -0
- package/project/.sdk/tm/c/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/c/tests/feature/secrets/secrets_test.c +802 -0
- package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +38 -11
- package/project/.sdk/tm/clojure/test/sdk/test/feature/secrets.clj +40 -6
- package/project/.sdk/tm/cpp/Makefile +48 -4
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.cpp +121 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.hpp +41 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.cpp +60 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.hpp +66 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.cpp +376 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/config.hpp +29 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.cpp +230 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.hpp +31 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.cpp +205 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/env.hpp +25 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.cpp +84 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/export.hpp +24 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.cpp +222 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.hpp +21 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.cpp +1200 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/host.hpp +250 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.cpp +250 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/order.hpp +22 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.cpp +110 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/point.hpp +79 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.cpp +136 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.hpp +60 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.cpp +82 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.hpp +25 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.cpp +90 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/types.hpp +65 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.cpp +491 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/value.hpp +120 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.cpp +143 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugin/version.hpp +36 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.cpp +248 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.hpp +30 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.cpp +149 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.cpp +117 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.hpp +27 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.cpp +180 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.hpp +52 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.cpp +87 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.cpp +121 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.cpp +153 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.cpp +666 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.hpp +160 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.cpp +123 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.cpp +125 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.hpp +23 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.cpp +223 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.hpp +47 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.cpp +104 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.hpp +27 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.cpp +242 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.hpp +58 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.cpp +260 -0
- package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.hpp +47 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.cpp +476 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.hpp +89 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.cpp +312 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.hpp +263 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.cpp +354 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.hpp +111 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.cpp +613 -0
- package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.hpp +227 -0
- package/project/.sdk/tm/cpp/feature/secrets.hpp +745 -0
- package/project/.sdk/tm/cpp/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/cpp/test/feature/secrets/secrets_test.cpp +808 -0
- package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +34 -8
- package/project/.sdk/tm/csharp/test/feature/secrets/SecretsFeatureTest.cs +85 -0
- package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +17 -2
- package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +41 -0
- package/project/.sdk/tm/go/feature/secrets_feature.go +32 -10
- package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +116 -0
- package/project/.sdk/tm/java/feature/SecretsFeature.java +33 -8
- package/project/.sdk/tm/java/test/feature/secrets/SecretsFeatureTest.java +64 -0
- package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +34 -11
- package/project/.sdk/tm/js/test/feature/secrets/Secrets.test.js +73 -0
- package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +32 -7
- package/project/.sdk/tm/kotlin/test/feature/secrets/SecretsTest.kt +69 -0
- package/project/.sdk/tm/lua/Makefile +15 -4
- package/project/.sdk/tm/lua/feature/secrets/native/sekretonet.c +806 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/capability.lua +135 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/catalog.lua +63 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/config.lua +361 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/depend.lua +232 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/env.lua +168 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/export.lua +66 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/graph.lua +194 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/host.lua +1190 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/json.lua +169 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/order.lua +207 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/point.lua +106 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/ref.lua +115 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/resolve.lua +78 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/types.lua +275 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin/version.lua +131 -0
- package/project/.sdk/tm/lua/feature/secrets/plugin.lua +76 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/addr.lua +124 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/err.lua +47 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/name.lua +315 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/aws.lua +228 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/azuresecrets.lua +137 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/boru.lua +124 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/crypto.lua +212 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/doppler.lua +89 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/gcpsecrets.lua +129 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/hashicorp.lua +154 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/httpjson.lua +248 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/infisical.lua +113 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/json.lua +449 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/net.lua +198 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/onepassword.lua +126 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/secretspec.lua +93 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/sigv4.lua +269 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/support.lua +146 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto/providers.lua +346 -0
- package/project/.sdk/tm/lua/feature/secrets/sekreto.lua +479 -0
- package/project/.sdk/tm/lua/feature/secrets_feature.lua +690 -0
- package/project/.sdk/tm/lua/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/lua/test/extend_test.lua +105 -0
- package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +862 -0
- package/project/.sdk/tm/ocaml/Makefile +52 -8
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/capability.ml +106 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/catalog.ml +43 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/config.ml +349 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/defs.ml +143 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/depend.ml +217 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/env.ml +197 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/export.ml +89 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/graph.ml +227 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/host.ml +1112 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/order.ml +202 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/point.ml +138 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/ref.ml +126 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/resolve.ml +62 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/types.ml +97 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/value.ml +387 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugin/version.ml +139 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/aws.ml +171 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/azuresecrets.ml +116 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/boru.ml +95 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/crypto.ml +149 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/doppler.ml +61 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/gcpsecrets.ml +93 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/hashicorp.ml +120 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/http.ml +421 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/httpjson.ml +66 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/infisical.ml +85 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/onepassword.ml +112 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/runcmd.ml +97 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/secretspec.ml +68 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/sigv4.ml +259 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls.ml +44 -0
- package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls_stubs.c +358 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/json.ml +376 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/provider.ml +647 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/secret.ml +299 -0
- package/project/.sdk/tm/ocaml/feature/secrets/sekreto/sekreto.ml +347 -0
- package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +453 -0
- package/project/.sdk/tm/ocaml/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +670 -0
- package/project/.sdk/tm/perl/feature/secrets_feature.pm +33 -12
- package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +47 -0
- package/project/.sdk/tm/php/feature/SecretsFeature.php +30 -6
- package/project/.sdk/tm/php/test/feature/secrets/SecretsTest.php +98 -0
- package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +28 -6
- package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +114 -0
- package/project/.sdk/tm/rb/feature/secrets_feature.rb +28 -6
- package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +93 -0
- package/project/.sdk/tm/rust/feature/secrets.rs +33 -10
- package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +96 -0
- package/project/.sdk/tm/scala/feature/SecretsFeature.scala +29 -7
- package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +71 -0
- package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +35 -12
- package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +73 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/capability.zig +137 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/catalog.zig +90 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/config.zig +346 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/depend.zig +244 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/env.zig +201 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/export.zig +83 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/graph.zig +212 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/host.zig +1224 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/inst.zig +126 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/order.zig +228 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/plugin.zig +34 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/point.zig +166 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/ref.zig +147 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/resolve.zig +74 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/types.zig +140 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/value.zig +662 -0
- package/project/.sdk/tm/zig/feature/secrets/plugin/version.zig +139 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/aws.zig +294 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/azuresecrets.zig +222 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/boru.zig +188 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/doppler.zig +135 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/gcpsecrets.zig +170 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/hashicorp.zig +242 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/httpjson.zig +535 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/infisical.zig +167 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/onepassword.zig +202 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/secretspec.zig +160 -0
- package/project/.sdk/tm/zig/feature/secrets/plugins/sigv4.zig +336 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/addr.zig +148 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/builtins.zig +259 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/provider.zig +440 -0
- package/project/.sdk/tm/zig/feature/secrets/sekreto/sekreto.zig +944 -0
- package/project/.sdk/tm/zig/feature/secrets.zig +854 -0
- package/project/.sdk/tm/zig/src/feature/secrets/.gitkeep +0 -0
- package/project/.sdk/tm/zig/test/feature/secrets/secrets_test.zig +891 -0
- package/project/sdkgen-package.json +1 -1
|
@@ -0,0 +1,421 @@
|
|
|
1
|
+
(* VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (ocaml/plugins/http.ml) *)
|
|
2
|
+
(* Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0] *)
|
|
3
|
+
(* License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream. *)
|
|
4
|
+
(* Just enough HTTP to ask a vault for a secret.
|
|
5
|
+
|
|
6
|
+
OCaml's distribution has sockets and no HTTP client, so this speaks
|
|
7
|
+
HTTP/1.1 over a Unix socket directly: a GET or POST with headers and an
|
|
8
|
+
optional body, a status line, and a response body delimited by
|
|
9
|
+
Content-Length, by chunks, or by the connection closing. That is the
|
|
10
|
+
house rule - HTTP framing is written in-tree - and it is why the port
|
|
11
|
+
binds libssl rather than libcurl.
|
|
12
|
+
|
|
13
|
+
https rides plugins/tls.ml, which is the whole of the port's third-party
|
|
14
|
+
surface.
|
|
15
|
+
|
|
16
|
+
It is deliberately not a general-purpose client.
|
|
17
|
+
|
|
18
|
+
NO REDIRECTS. A vault API does not legitimately redirect, and a followed
|
|
19
|
+
redirect would carry X-Vault-Token to a host `checkaddr` never saw, and
|
|
20
|
+
could downgrade https to http.
|
|
21
|
+
|
|
22
|
+
NO PROXIES. Nothing here reads http_proxy, https_proxy or ALL_PROXY. The
|
|
23
|
+
GCP and Azure metadata endpoints are not loopback, and a proxy variable
|
|
24
|
+
in the environment has sent a Vault token in the clear before. *)
|
|
25
|
+
|
|
26
|
+
open Secret
|
|
27
|
+
|
|
28
|
+
(* How long reaching a vault may take before it is treated as unreachable.
|
|
29
|
+
Ports carry the same bound. *)
|
|
30
|
+
let timeout = 10.0
|
|
31
|
+
|
|
32
|
+
(* How much of a response body will be read before the store is treated as
|
|
33
|
+
having answered incoherently. Ports carry the same bound.
|
|
34
|
+
|
|
35
|
+
Far above anything real - the largest legitimate payload this library
|
|
36
|
+
fetches is Doppler's whole-config download, measured in kilobytes. A
|
|
37
|
+
bound is needed because the timeout is not one: it is per read, so a
|
|
38
|
+
server that keeps sending resets it forever, and the body is accumulated
|
|
39
|
+
in memory before it is parsed. This runs on an application's startup
|
|
40
|
+
path, so the failure is the application never starting. *)
|
|
41
|
+
let maxbody = 8 * 1024 * 1024
|
|
42
|
+
|
|
43
|
+
type response = { status : int; body : string }
|
|
44
|
+
|
|
45
|
+
(* A url split into the parts a request needs. *)
|
|
46
|
+
type target = {
|
|
47
|
+
(* The bare host: what we connect to, and what the certificate is checked
|
|
48
|
+
against. An IPv6 literal appears here without brackets. *)
|
|
49
|
+
host : string;
|
|
50
|
+
(* The authority as it goes in the `Host:` header. An IPv6 literal keeps
|
|
51
|
+
its brackets, because `Host: 2001:db8::1:8200` is not a valid authority
|
|
52
|
+
and an intermediary may reject or misroute it. *)
|
|
53
|
+
authority : string;
|
|
54
|
+
port : int;
|
|
55
|
+
path : string;
|
|
56
|
+
tls : bool;
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
(* A url without its query string, for a message that must not leak one.
|
|
60
|
+
|
|
61
|
+
A query here carries the vault path, the secret name or a filter -
|
|
62
|
+
`secretPath=/prod/payments/stripe` - which does not belong in a log. *)
|
|
63
|
+
let bare (url : string) : string =
|
|
64
|
+
match String.index_opt url '?' with None -> url | Some at -> String.sub url 0 at
|
|
65
|
+
|
|
66
|
+
let unreachable (url : string) (why : string) : 'a =
|
|
67
|
+
fail ("sekreto: cannot reach " ^ bare url ^ ": " ^ why)
|
|
68
|
+
|
|
69
|
+
let split (url : string) : target =
|
|
70
|
+
let rest, tls, defaultport =
|
|
71
|
+
if String.starts_with ~prefix:"https://" url then
|
|
72
|
+
(String.sub url 8 (String.length url - 8), true, 443)
|
|
73
|
+
else if String.starts_with ~prefix:"http://" url then
|
|
74
|
+
(String.sub url 7 (String.length url - 7), false, 80)
|
|
75
|
+
else fail ("sekreto: not an http url: " ^ bare url)
|
|
76
|
+
in
|
|
77
|
+
|
|
78
|
+
let authority, path =
|
|
79
|
+
match String.index_opt rest '/' with
|
|
80
|
+
| Some at -> (String.sub rest 0 at, String.sub rest at (String.length rest - at))
|
|
81
|
+
| None -> (rest, "/")
|
|
82
|
+
in
|
|
83
|
+
|
|
84
|
+
(* rindex, so that an IPv6 literal's own colons are not mistaken for a
|
|
85
|
+
port separator when one is present. *)
|
|
86
|
+
let hostpart, port =
|
|
87
|
+
match String.rindex_opt authority ':' with
|
|
88
|
+
| Some at
|
|
89
|
+
when at + 1 < String.length authority
|
|
90
|
+
&& not (String.ends_with ~suffix:"]" authority) ->
|
|
91
|
+
let text = String.sub authority (at + 1) (String.length authority - at - 1) in
|
|
92
|
+
(String.sub authority 0 at, match int_of_string_opt text with Some p -> p | None -> defaultport)
|
|
93
|
+
| _ -> (authority, defaultport)
|
|
94
|
+
in
|
|
95
|
+
|
|
96
|
+
let stripped =
|
|
97
|
+
let len = String.length hostpart in
|
|
98
|
+
if len >= 2 && '[' = hostpart.[0] && ']' = hostpart.[len - 1] then String.sub hostpart 1 (len - 2)
|
|
99
|
+
else hostpart
|
|
100
|
+
in
|
|
101
|
+
|
|
102
|
+
(* Re-bracketed only if it really is an IPv6 literal. *)
|
|
103
|
+
let header = if String.contains stripped ':' then "[" ^ stripped ^ "]" else stripped in
|
|
104
|
+
|
|
105
|
+
{ host = stripped; authority = header; port; path; tls }
|
|
106
|
+
|
|
107
|
+
(* Connect, under ONE deadline across every address the name resolves to.
|
|
108
|
+
|
|
109
|
+
A name commonly resolves to several - a dual-stack host answers with both
|
|
110
|
+
an A and an AAAA - and giving each the full ten seconds would make the
|
|
111
|
+
real bound ten seconds times however many addresses the name cares to
|
|
112
|
+
return, which is not a bound at all when the name is the attacker's.
|
|
113
|
+
Each attempt gets what is left of the one deadline. *)
|
|
114
|
+
let connectall (addrs : Unix.sockaddr list) (budget : float) : Unix.file_descr =
|
|
115
|
+
let started = Unix.gettimeofday () in
|
|
116
|
+
let last = ref "no address" in
|
|
117
|
+
|
|
118
|
+
let rec attempt = function
|
|
119
|
+
| [] -> failwith !last
|
|
120
|
+
| addr :: rest ->
|
|
121
|
+
let left = budget -. (Unix.gettimeofday () -. started) in
|
|
122
|
+
if left <= 0.0 then failwith !last
|
|
123
|
+
else begin
|
|
124
|
+
let domain = Unix.domain_of_sockaddr addr in
|
|
125
|
+
let fd = Unix.socket domain Unix.SOCK_STREAM 0 in
|
|
126
|
+
match
|
|
127
|
+
Unix.set_nonblock fd;
|
|
128
|
+
(try Unix.connect fd addr with
|
|
129
|
+
| Unix.Unix_error ((Unix.EINPROGRESS | Unix.EWOULDBLOCK | Unix.EAGAIN), _, _) -> ());
|
|
130
|
+
let _, writable, _ = Unix.select [] [ fd ] [] left in
|
|
131
|
+
if [] = writable then failwith "timed out";
|
|
132
|
+
(match Unix.getsockopt_error fd with
|
|
133
|
+
| Some err -> raise (Unix.Unix_error (err, "connect", ""))
|
|
134
|
+
| None -> ());
|
|
135
|
+
Unix.clear_nonblock fd
|
|
136
|
+
with
|
|
137
|
+
| () -> fd
|
|
138
|
+
| exception Unix.Unix_error (err, _, _) ->
|
|
139
|
+
(try Unix.close fd with _ -> ());
|
|
140
|
+
last := Unix.error_message err;
|
|
141
|
+
attempt rest
|
|
142
|
+
| exception Failure why ->
|
|
143
|
+
(try Unix.close fd with _ -> ());
|
|
144
|
+
last := why;
|
|
145
|
+
attempt rest
|
|
146
|
+
end
|
|
147
|
+
in
|
|
148
|
+
|
|
149
|
+
attempt addrs
|
|
150
|
+
|
|
151
|
+
let connect (target : target) (url : string) : Unix.file_descr =
|
|
152
|
+
let addrs =
|
|
153
|
+
try
|
|
154
|
+
List.map
|
|
155
|
+
(fun (info : Unix.addr_info) -> info.Unix.ai_addr)
|
|
156
|
+
(Unix.getaddrinfo target.host (string_of_int target.port)
|
|
157
|
+
[ Unix.AI_SOCKTYPE Unix.SOCK_STREAM ])
|
|
158
|
+
with Unix.Unix_error (err, _, _) -> unreachable url (Unix.error_message err)
|
|
159
|
+
in
|
|
160
|
+
|
|
161
|
+
if [] = addrs then unreachable url "no address";
|
|
162
|
+
|
|
163
|
+
let fd = try connectall addrs timeout with Failure why -> unreachable url why in
|
|
164
|
+
|
|
165
|
+
(* A write blocks too, once the peer's receive window fills and it stops
|
|
166
|
+
reading, so both directions are bounded. *)
|
|
167
|
+
(try
|
|
168
|
+
Unix.setsockopt_float fd Unix.SO_RCVTIMEO timeout;
|
|
169
|
+
Unix.setsockopt_float fd Unix.SO_SNDTIMEO timeout
|
|
170
|
+
with Unix.Unix_error _ -> ());
|
|
171
|
+
|
|
172
|
+
fd
|
|
173
|
+
|
|
174
|
+
(* Whatever the exchange runs over: a plain socket, or a TLS session on one. *)
|
|
175
|
+
type channel = Plain of Unix.file_descr | Secure of Tls.conn * Unix.file_descr
|
|
176
|
+
|
|
177
|
+
let chanwrite (chan : channel) (text : string) : int -> int -> int =
|
|
178
|
+
fun ofs len ->
|
|
179
|
+
match chan with
|
|
180
|
+
| Plain fd -> Unix.write_substring fd text ofs len
|
|
181
|
+
| Secure (conn, _) -> Tls.write conn text ofs len
|
|
182
|
+
|
|
183
|
+
let chanread (chan : channel) (buf : Bytes.t) (ofs : int) (len : int) : int =
|
|
184
|
+
match chan with
|
|
185
|
+
| Plain fd -> Unix.read fd buf ofs len
|
|
186
|
+
| Secure (conn, _) -> Tls.read conn buf ofs len
|
|
187
|
+
|
|
188
|
+
let chanclose (chan : channel) : unit =
|
|
189
|
+
match chan with
|
|
190
|
+
| Plain fd -> ( try Unix.close fd with _ -> ())
|
|
191
|
+
| Secure (conn, fd) ->
|
|
192
|
+
(try Tls.close conn with _ -> ());
|
|
193
|
+
(try Unix.close fd with _ -> ())
|
|
194
|
+
|
|
195
|
+
let writeall (chan : channel) (text : string) (url : string) : unit =
|
|
196
|
+
let len = String.length text in
|
|
197
|
+
let at = ref 0 in
|
|
198
|
+
while !at < len do
|
|
199
|
+
match chanwrite chan text !at (len - !at) with
|
|
200
|
+
| 0 -> unreachable url "connection closed while writing"
|
|
201
|
+
| wrote -> at := !at + wrote
|
|
202
|
+
| exception Unix.Unix_error (err, _, _) -> unreachable url (Unix.error_message err)
|
|
203
|
+
| exception Failure why -> unreachable url why
|
|
204
|
+
done
|
|
205
|
+
|
|
206
|
+
(* The offset of `needle` in `hay`, if it is there. *)
|
|
207
|
+
let findbytes (hay : string) (needle : string) : int option =
|
|
208
|
+
let hlen = String.length hay and nlen = String.length needle in
|
|
209
|
+
let rec walk index =
|
|
210
|
+
if index + nlen > hlen then None
|
|
211
|
+
else if String.sub hay index nlen = needle then Some index
|
|
212
|
+
else walk (index + 1)
|
|
213
|
+
in
|
|
214
|
+
walk 0
|
|
215
|
+
|
|
216
|
+
(* Join a chunked body back together.
|
|
217
|
+
|
|
218
|
+
Each chunk is a hex length, CRLF, that many bytes, CRLF. A zero length
|
|
219
|
+
ends the body; any trailer after it is ignored.
|
|
220
|
+
|
|
221
|
+
Bytes, not characters: a chunk length counts bytes and a boundary may
|
|
222
|
+
fall inside a multibyte character, so a secret with any non-ASCII
|
|
223
|
+
character in it would otherwise be cut in half. *)
|
|
224
|
+
let dechunk (raw : string) : string option =
|
|
225
|
+
let out = Buffer.create (String.length raw) in
|
|
226
|
+
let len = String.length raw in
|
|
227
|
+
|
|
228
|
+
let rec walk at =
|
|
229
|
+
match
|
|
230
|
+
let rec find index =
|
|
231
|
+
if index + 2 > len then None
|
|
232
|
+
else if String.sub raw index 2 = "\r\n" then Some index
|
|
233
|
+
else find (index + 1)
|
|
234
|
+
in
|
|
235
|
+
find at
|
|
236
|
+
with
|
|
237
|
+
| None -> None
|
|
238
|
+
| Some mark ->
|
|
239
|
+
let header = String.sub raw at (mark - at) in
|
|
240
|
+
let head = match String.index_opt header ';' with
|
|
241
|
+
| None -> header
|
|
242
|
+
| Some at -> String.sub header 0 at
|
|
243
|
+
in
|
|
244
|
+
(match int_of_string_opt ("0x" ^ trim head) with
|
|
245
|
+
| None -> None
|
|
246
|
+
| Some 0 -> Some (Buffer.contents out)
|
|
247
|
+
| Some size ->
|
|
248
|
+
let body = mark + 2 in
|
|
249
|
+
if body + size > len then None
|
|
250
|
+
else begin
|
|
251
|
+
Buffer.add_string out (String.sub raw body size);
|
|
252
|
+
walk (body + size + 2)
|
|
253
|
+
end)
|
|
254
|
+
in
|
|
255
|
+
|
|
256
|
+
walk 0
|
|
257
|
+
|
|
258
|
+
(* One HTTP exchange: any method, a set of headers, an optional body. A
|
|
259
|
+
non-2xx status is answered, not raised: a 404 from a vault means "no such
|
|
260
|
+
secret", which is a miss rather than a failure. *)
|
|
261
|
+
let request (meth : string) (url : string) (headers : (string * string) list)
|
|
262
|
+
(body : string option) : response =
|
|
263
|
+
let target = split url in
|
|
264
|
+
let fd = connect target url in
|
|
265
|
+
|
|
266
|
+
let chan =
|
|
267
|
+
if target.tls then
|
|
268
|
+
match Tls.connect fd target.host with
|
|
269
|
+
| conn -> Secure (conn, fd)
|
|
270
|
+
| exception Failure why ->
|
|
271
|
+
(try Unix.close fd with _ -> ());
|
|
272
|
+
unreachable url why
|
|
273
|
+
else Plain fd
|
|
274
|
+
in
|
|
275
|
+
|
|
276
|
+
let finish () = chanclose chan in
|
|
277
|
+
|
|
278
|
+
match
|
|
279
|
+
(* A default port stays implicit in the Host header, the way a URL
|
|
280
|
+
normalises it: a SigV4 signature covers `host`, and `Host: x:443` is
|
|
281
|
+
not what was signed. *)
|
|
282
|
+
let hostheader =
|
|
283
|
+
if (target.tls && 443 = target.port) || ((not target.tls) && 80 = target.port) then
|
|
284
|
+
target.authority
|
|
285
|
+
else target.authority ^ ":" ^ string_of_int target.port
|
|
286
|
+
in
|
|
287
|
+
|
|
288
|
+
let out = Buffer.create 512 in
|
|
289
|
+
Buffer.add_string out (meth ^ " " ^ target.path ^ " HTTP/1.1\r\n");
|
|
290
|
+
Buffer.add_string out ("Host: " ^ hostheader ^ "\r\n");
|
|
291
|
+
Buffer.add_string out "Accept: application/json\r\n";
|
|
292
|
+
Buffer.add_string out "Connection: close\r\n";
|
|
293
|
+
List.iter (fun (name, value) -> Buffer.add_string out (name ^ ": " ^ value ^ "\r\n")) headers;
|
|
294
|
+
(match body with
|
|
295
|
+
| Some text -> Buffer.add_string out ("Content-Length: " ^ string_of_int (String.length text) ^ "\r\n")
|
|
296
|
+
| None -> ());
|
|
297
|
+
Buffer.add_string out "\r\n";
|
|
298
|
+
(match body with Some text -> Buffer.add_string out text | None -> ());
|
|
299
|
+
|
|
300
|
+
writeall chan (Buffer.contents out) url;
|
|
301
|
+
|
|
302
|
+
(* Bounded, not read-to-end: an endless body would otherwise be
|
|
303
|
+
accumulated in memory until the deadline, which on a loopback or
|
|
304
|
+
datacentre link is gigabytes. One byte over the bound is enough to
|
|
305
|
+
know it was exceeded, and an endless body is a store that could not
|
|
306
|
+
answer - so this is an error, never a miss. *)
|
|
307
|
+
let held = Buffer.create 8192 in
|
|
308
|
+
let chunk = Bytes.create 65536 in
|
|
309
|
+
let reading = ref true in
|
|
310
|
+
|
|
311
|
+
while !reading do
|
|
312
|
+
if Buffer.length held > maxbody then reading := false
|
|
313
|
+
else
|
|
314
|
+
match chanread chan chunk 0 65536 with
|
|
315
|
+
| 0 -> reading := false
|
|
316
|
+
| got -> Buffer.add_subbytes held chunk 0 got
|
|
317
|
+
| exception Unix.Unix_error ((Unix.EAGAIN | Unix.EWOULDBLOCK), _, _) ->
|
|
318
|
+
unreachable url "timed out"
|
|
319
|
+
| exception Unix.Unix_error (err, _, _) -> unreachable url (Unix.error_message err)
|
|
320
|
+
| exception Failure why -> unreachable url why
|
|
321
|
+
done;
|
|
322
|
+
|
|
323
|
+
if Buffer.length held > maxbody then fail ("sekreto: oversized response from " ^ bare url);
|
|
324
|
+
|
|
325
|
+
let raw = Buffer.contents held in
|
|
326
|
+
|
|
327
|
+
let split_at =
|
|
328
|
+
match findbytes raw "\r\n\r\n" with
|
|
329
|
+
| Some at -> at
|
|
330
|
+
| None -> fail ("sekreto: malformed response from " ^ bare url)
|
|
331
|
+
in
|
|
332
|
+
|
|
333
|
+
(* Headers are ASCII; the body is not necessarily, so it stays bytes
|
|
334
|
+
until every length-counted slice has been taken. *)
|
|
335
|
+
let head = String.sub raw 0 split_at in
|
|
336
|
+
let rawbody = String.sub raw (split_at + 4) (String.length raw - split_at - 4) in
|
|
337
|
+
|
|
338
|
+
let lines = String.split_on_char '\n' head in
|
|
339
|
+
let statusline = match lines with first :: _ -> first | [] -> "" in
|
|
340
|
+
|
|
341
|
+
let status =
|
|
342
|
+
match String.split_on_char ' ' (String.trim statusline) with
|
|
343
|
+
| _ :: code :: _ -> ( match int_of_string_opt code with Some value -> value | None -> -1)
|
|
344
|
+
| _ -> -1
|
|
345
|
+
in
|
|
346
|
+
|
|
347
|
+
if -1 = status then fail ("sekreto: malformed response from " ^ bare url);
|
|
348
|
+
|
|
349
|
+
let chunked =
|
|
350
|
+
List.exists
|
|
351
|
+
(fun line ->
|
|
352
|
+
match String.index_opt line ':' with
|
|
353
|
+
| None -> false
|
|
354
|
+
| Some at ->
|
|
355
|
+
let name = String.lowercase_ascii (trim (String.sub line 0 at)) in
|
|
356
|
+
let value = String.lowercase_ascii (String.sub line (at + 1) (String.length line - at - 1)) in
|
|
357
|
+
"transfer-encoding" = name
|
|
358
|
+
&& None <> findsub value "chunked")
|
|
359
|
+
(match lines with _ :: rest -> rest | [] -> [])
|
|
360
|
+
in
|
|
361
|
+
|
|
362
|
+
let text =
|
|
363
|
+
if chunked then
|
|
364
|
+
match dechunk rawbody with
|
|
365
|
+
| Some value -> value
|
|
366
|
+
| None -> fail ("sekreto: malformed response from " ^ bare url)
|
|
367
|
+
else rawbody
|
|
368
|
+
in
|
|
369
|
+
|
|
370
|
+
{ status; body = text }
|
|
371
|
+
with
|
|
372
|
+
| answer ->
|
|
373
|
+
finish ();
|
|
374
|
+
answer
|
|
375
|
+
| exception err ->
|
|
376
|
+
finish ();
|
|
377
|
+
raise err
|
|
378
|
+
|
|
379
|
+
(* Decode standard base64: an AWS SecretBinary, a GCP secret payload.
|
|
380
|
+
|
|
381
|
+
STRICT, deliberately. A lenient decoder skips bytes outside the alphabet
|
|
382
|
+
and hands back plausible-looking bytes for a corrupted payload - which
|
|
383
|
+
then get returned as the secret. Whitespace is stripped first, because
|
|
384
|
+
the canonical function accepts embedded newlines; everything else outside
|
|
385
|
+
`A-Za-z0-9+/` with at most two trailing `=`, and any length that is not a
|
|
386
|
+
multiple of four, is refused. A refusal is an error, never a miss. *)
|
|
387
|
+
let unbase64 (text : string) : string option =
|
|
388
|
+
let alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/" in
|
|
389
|
+
|
|
390
|
+
let packed = Buffer.create (String.length text) in
|
|
391
|
+
String.iter
|
|
392
|
+
(fun ch -> match ch with ' ' | '\t' | '\n' | '\r' | '\012' -> () | _ -> Buffer.add_char packed ch)
|
|
393
|
+
text;
|
|
394
|
+
let body = Buffer.contents packed in
|
|
395
|
+
let len = String.length body in
|
|
396
|
+
|
|
397
|
+
let pad =
|
|
398
|
+
if len >= 2 && '=' = body.[len - 1] && '=' = body.[len - 2] then 2
|
|
399
|
+
else if len >= 1 && '=' = body.[len - 1] then 1
|
|
400
|
+
else 0
|
|
401
|
+
in
|
|
402
|
+
let core = String.sub body 0 (len - pad) in
|
|
403
|
+
|
|
404
|
+
if 0 <> len mod 4 then None
|
|
405
|
+
else if not (String.for_all (fun ch -> String.contains alphabet ch) core) then None
|
|
406
|
+
else begin
|
|
407
|
+
let out = Buffer.create len in
|
|
408
|
+
let acc = ref 0 and bits = ref 0 in
|
|
409
|
+
|
|
410
|
+
String.iter
|
|
411
|
+
(fun ch ->
|
|
412
|
+
acc := (!acc lsl 6) lor String.index alphabet ch;
|
|
413
|
+
bits := !bits + 6;
|
|
414
|
+
if 8 <= !bits then begin
|
|
415
|
+
bits := !bits - 8;
|
|
416
|
+
Buffer.add_char out (Char.chr ((!acc lsr !bits) land 0xff))
|
|
417
|
+
end)
|
|
418
|
+
core;
|
|
419
|
+
|
|
420
|
+
Some (Buffer.contents out)
|
|
421
|
+
end
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
(* VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (ocaml/plugins/httpjson.ml) *)
|
|
2
|
+
(* Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0] *)
|
|
3
|
+
(* License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream. *)
|
|
4
|
+
(* One JSON round-trip, and the reads a response body needs.
|
|
5
|
+
|
|
6
|
+
THE SHARED HTTP-JSON HELPER, AND IT LIVES UNDER plugins/ BECAUSE OF
|
|
7
|
+
THAT. Seven of the ten plugin kinds dial a store over HTTPS; the four
|
|
8
|
+
built-in kinds dial nothing, so a chain of built-ins must never link
|
|
9
|
+
this module, the framing under it or the TLS binding under that. *)
|
|
10
|
+
|
|
11
|
+
open Secret
|
|
12
|
+
|
|
13
|
+
(* A url without its query string, for a message that must not leak one. *)
|
|
14
|
+
let bare = Http.bare
|
|
15
|
+
|
|
16
|
+
(* One JSON round-trip's result: the status, and the parsed body. *)
|
|
17
|
+
type answer = { status : int; jbody : Json.t option }
|
|
18
|
+
|
|
19
|
+
(* One JSON round-trip. Network failure is always an error - an unreachable
|
|
20
|
+
store is a store that could not answer, never a store without the
|
|
21
|
+
secret. *)
|
|
22
|
+
let fetchjson ?(headers = []) ?body (meth : string) (url : string) : answer =
|
|
23
|
+
let res = Http.request meth url headers body in
|
|
24
|
+
let parsed = Json.parse res.Http.body in
|
|
25
|
+
|
|
26
|
+
(* A success status promised JSON; a body that does not parse means the
|
|
27
|
+
store could not answer coherently, and treating it as a miss would fall
|
|
28
|
+
through to a weaker store. Error statuses may carry any body - they are
|
|
29
|
+
decided on status alone. *)
|
|
30
|
+
if 200 = res.Http.status && None = parsed then
|
|
31
|
+
fail ("sekreto: malformed response from " ^ bare url);
|
|
32
|
+
|
|
33
|
+
{ status = res.Http.status; jbody = parsed }
|
|
34
|
+
|
|
35
|
+
(* When a logged-in token must be renewed, from its expiry in seconds (a
|
|
36
|
+
JSON number, or a string as Azure IMDS sends it): now + max(seconds - 60,
|
|
37
|
+
1). A missing or zero expiry means never renew. *)
|
|
38
|
+
let never = infinity
|
|
39
|
+
|
|
40
|
+
let renewtime (expires : Json.t option) : float =
|
|
41
|
+
let seconds =
|
|
42
|
+
match expires with
|
|
43
|
+
| Some (Json.Num value) -> value
|
|
44
|
+
| Some (Json.Str value) -> ( match float_of_string_opt value with Some v -> v | None -> 0.0)
|
|
45
|
+
| _ -> 0.0
|
|
46
|
+
in
|
|
47
|
+
if Float.is_nan seconds || 0.0 >= seconds then never
|
|
48
|
+
else (Unix.gettimeofday () *. 1000.0) +. (Float.max (seconds -. 60.0) 1.0 *. 1000.0)
|
|
49
|
+
|
|
50
|
+
let nowms () : float = Unix.gettimeofday () *. 1000.0
|
|
51
|
+
|
|
52
|
+
(* ---- reading a response ---------------------------------------------- *)
|
|
53
|
+
|
|
54
|
+
(* The text at a path in a response body, or nothing. A JSON null is nothing
|
|
55
|
+
- a null field is a miss, never the string `null`. *)
|
|
56
|
+
let digtext (body : Json.t option) (keys : string list) : string option =
|
|
57
|
+
Json.otext (Json.odig body keys)
|
|
58
|
+
|
|
59
|
+
(* The string at a path, insisting it really is a string: `__type` must be
|
|
60
|
+
one, a 1Password vault list must be an array, a Doppler config an
|
|
61
|
+
object. *)
|
|
62
|
+
let digstr (body : Json.t option) (keys : string list) : string option =
|
|
63
|
+
Json.oasstr (Json.odig body keys)
|
|
64
|
+
|
|
65
|
+
let isset (value : string option) : bool =
|
|
66
|
+
match value with Some text -> "" <> text | None -> false
|
|
@@ -0,0 +1,85 @@
|
|
|
1
|
+
(* VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (ocaml/plugins/infisical.ml) *)
|
|
2
|
+
(* Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0] *)
|
|
3
|
+
(* License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream. *)
|
|
4
|
+
(* The `infisical` provider kind, as a voxgig/plugin definition.
|
|
5
|
+
|
|
6
|
+
The Infisical API over HTTPS, with universal auth as the source of a
|
|
7
|
+
token.
|
|
8
|
+
|
|
9
|
+
A port of typescript/plugins/infisical.ts, which is canonical. *)
|
|
10
|
+
|
|
11
|
+
open Secret
|
|
12
|
+
open Provider
|
|
13
|
+
open Httpjson
|
|
14
|
+
|
|
15
|
+
(* Infisical.
|
|
16
|
+
|
|
17
|
+
`api.token` reads the secret keyed `API_TOKEN` (Infisical's own
|
|
18
|
+
convention is environment-style keys) at a secret path in one environment
|
|
19
|
+
of a project. Auth is a token, or a universal-auth (machine identity)
|
|
20
|
+
login. Its expiry field is `expiresIn`, camelCase, unlike everyone
|
|
21
|
+
else's `expires_in`. *)
|
|
22
|
+
let infisical_provider (addr : string) (token : string) (clientid : string)
|
|
23
|
+
(clientsecret : string) (project : string) (environment : string) (secretpath : string) :
|
|
24
|
+
provider =
|
|
25
|
+
let livetoken = ref None in
|
|
26
|
+
let renewat = ref never in
|
|
27
|
+
|
|
28
|
+
let login useaddr =
|
|
29
|
+
if "" <> token then token
|
|
30
|
+
else begin
|
|
31
|
+
if "" = clientid || "" = clientsecret then
|
|
32
|
+
fail "sekreto: infisical: no token and no client credentials";
|
|
33
|
+
|
|
34
|
+
let body =
|
|
35
|
+
Json.obj [ ("clientId", Json.str clientid); ("clientSecret", Json.str clientsecret) ]
|
|
36
|
+
in
|
|
37
|
+
|
|
38
|
+
let res =
|
|
39
|
+
fetchjson
|
|
40
|
+
~headers:[ ("content-type", "application/json") ]
|
|
41
|
+
~body:(Json.stringify body) "POST"
|
|
42
|
+
(useaddr ^ "/api/v1/auth/universal-auth/login")
|
|
43
|
+
in
|
|
44
|
+
|
|
45
|
+
let got = digtext res.jbody [ "accessToken" ] in
|
|
46
|
+
if 200 <> res.status || not (isset got) then
|
|
47
|
+
fail ("sekreto: infisical login failed: " ^ string_of_int res.status);
|
|
48
|
+
|
|
49
|
+
renewat := renewtime (Json.odig res.jbody [ "expiresIn" ]);
|
|
50
|
+
Option.get got
|
|
51
|
+
end
|
|
52
|
+
in
|
|
53
|
+
|
|
54
|
+
{
|
|
55
|
+
lookup =
|
|
56
|
+
(fun name ->
|
|
57
|
+
let useaddr = trimslash (firstof [ addr; "https://app.infisical.com" ]) in
|
|
58
|
+
checkaddr useaddr;
|
|
59
|
+
|
|
60
|
+
if "" = project || "" = environment then fail "sekreto: infisical: no project/environment";
|
|
61
|
+
|
|
62
|
+
if None = !livetoken || nowms () >= !renewat then livetoken := Some (login useaddr);
|
|
63
|
+
|
|
64
|
+
let url =
|
|
65
|
+
useaddr ^ "/api/v3/secrets/raw/" ^ envkey name ^ "?workspaceId="
|
|
66
|
+
^ Sigv4.uriescape project ^ "&environment=" ^ Sigv4.uriescape environment
|
|
67
|
+
^ "&secretPath=" ^ Sigv4.uriescape (firstof [ secretpath; "/" ])
|
|
68
|
+
in
|
|
69
|
+
|
|
70
|
+
let res =
|
|
71
|
+
fetchjson
|
|
72
|
+
~headers:[ ("authorization", "Bearer " ^ Option.value ~default:"" !livetoken) ]
|
|
73
|
+
"GET" url
|
|
74
|
+
in
|
|
75
|
+
|
|
76
|
+
if 404 = res.status then None
|
|
77
|
+
else if 200 <> res.status then fail ("sekreto: infisical error: " ^ string_of_int res.status)
|
|
78
|
+
else digtext res.jbody [ "secret"; "secretValue" ]);
|
|
79
|
+
describe = (fun () -> "infisical:" ^ project ^ "/" ^ environment);
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
let plugin () : Defs.definition =
|
|
83
|
+
providerplugin "infisical" (fun spec ->
|
|
84
|
+
infisical_provider spec.addr spec.token spec.clientid spec.clientsecret spec.project
|
|
85
|
+
spec.environment spec.secretpath)
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
(* VENDORED: @voxgig/sekreto sdk-20260908-1556-0 (ocaml/plugins/onepassword.ml) *)
|
|
2
|
+
(* Source: https://github.com/voxgig/sekreto @ 1267ee2e5f49566bc92695bc9eb3a60ef4924998 [tag: sdk-20260908-1556-0] *)
|
|
3
|
+
(* License: MIT (c) voxgig - see repository LICENSE. Do not edit: resync from upstream. *)
|
|
4
|
+
(* The `onepassword` provider kind, as a voxgig/plugin definition.
|
|
5
|
+
|
|
6
|
+
1Password Connect over HTTPS.
|
|
7
|
+
|
|
8
|
+
A port of typescript/plugins/onepassword.ts, which is canonical. *)
|
|
9
|
+
|
|
10
|
+
open Secret
|
|
11
|
+
open Provider
|
|
12
|
+
open Httpjson
|
|
13
|
+
|
|
14
|
+
(* 1Password, through a Connect server.
|
|
15
|
+
|
|
16
|
+
The item titled `api.token` (titles KEEP THEIR DOTS), in the named vault.
|
|
17
|
+
The value is the field with purpose PASSWORD, or the field labelled
|
|
18
|
+
`value`. A vault that cannot be found is an ERROR, not a miss - config
|
|
19
|
+
names it, so its absence is a broken store rather than a missing
|
|
20
|
+
secret. *)
|
|
21
|
+
let onepassword_provider (addr : string) (token : string) (vault : string) : provider =
|
|
22
|
+
let vaultid = ref None in
|
|
23
|
+
|
|
24
|
+
let auth () = [ ("authorization", "Bearer " ^ token) ] in
|
|
25
|
+
|
|
26
|
+
let resolvevault useaddr =
|
|
27
|
+
if "" = vault then fail "sekreto: onepassword: no vault";
|
|
28
|
+
|
|
29
|
+
let res = fetchjson ~headers:(auth ()) "GET" (useaddr ^ "/v1/vaults") in
|
|
30
|
+
let list = Json.oasarr res.jbody in
|
|
31
|
+
|
|
32
|
+
if 200 <> res.status || None = list then
|
|
33
|
+
fail ("sekreto: onepassword error: " ^ string_of_int res.status ^ ": listing vaults");
|
|
34
|
+
|
|
35
|
+
let entries = Option.get list in
|
|
36
|
+
let found =
|
|
37
|
+
List.find_opt
|
|
38
|
+
(fun entry ->
|
|
39
|
+
Some vault = Json.otext (Json.dig entry [ "id" ])
|
|
40
|
+
|| Some vault = Json.otext (Json.dig entry [ "name" ]))
|
|
41
|
+
entries
|
|
42
|
+
in
|
|
43
|
+
|
|
44
|
+
match found with
|
|
45
|
+
| Some entry -> Option.value ~default:"" (Json.otext (Json.dig entry [ "id" ]))
|
|
46
|
+
| None -> fail ("sekreto: onepassword: no vault named " ^ vault)
|
|
47
|
+
in
|
|
48
|
+
|
|
49
|
+
{
|
|
50
|
+
lookup =
|
|
51
|
+
(fun name ->
|
|
52
|
+
ignore (checkname name);
|
|
53
|
+
|
|
54
|
+
let useaddr = trimslash addr in
|
|
55
|
+
if "" = useaddr then fail "sekreto: onepassword: no addr";
|
|
56
|
+
checkaddr useaddr;
|
|
57
|
+
|
|
58
|
+
let id =
|
|
59
|
+
match !vaultid with
|
|
60
|
+
| Some found -> found
|
|
61
|
+
| None ->
|
|
62
|
+
let resolved = resolvevault useaddr in
|
|
63
|
+
vaultid := Some resolved;
|
|
64
|
+
resolved
|
|
65
|
+
in
|
|
66
|
+
|
|
67
|
+
let filter = Sigv4.uriescape ("title eq \"" ^ name ^ "\"") in
|
|
68
|
+
let found =
|
|
69
|
+
fetchjson ~headers:(auth ()) "GET" (useaddr ^ "/v1/vaults/" ^ id ^ "/items?filter=" ^ filter)
|
|
70
|
+
in
|
|
71
|
+
|
|
72
|
+
let items = Json.oasarr found.jbody in
|
|
73
|
+
if 200 <> found.status || None = items then
|
|
74
|
+
fail ("sekreto: onepassword error: " ^ string_of_int found.status ^ ": finding " ^ name);
|
|
75
|
+
|
|
76
|
+
match Option.get items with
|
|
77
|
+
(* No item with that title: a miss, and the chain carries on. *)
|
|
78
|
+
| [] -> None
|
|
79
|
+
| head :: _ ->
|
|
80
|
+
let itemid = Option.value ~default:"" (Json.otext (Json.dig head [ "id" ])) in
|
|
81
|
+
let item =
|
|
82
|
+
fetchjson ~headers:(auth ()) "GET" (useaddr ^ "/v1/vaults/" ^ id ^ "/items/" ^ itemid)
|
|
83
|
+
in
|
|
84
|
+
|
|
85
|
+
if 200 <> item.status then
|
|
86
|
+
fail ("sekreto: onepassword error: " ^ string_of_int item.status ^ ": reading " ^ name);
|
|
87
|
+
|
|
88
|
+
let fields =
|
|
89
|
+
match Json.oasarr (Json.odig item.jbody [ "fields" ]) with
|
|
90
|
+
| Some list -> list
|
|
91
|
+
| None -> []
|
|
92
|
+
in
|
|
93
|
+
|
|
94
|
+
(* Two full passes, in this order. *)
|
|
95
|
+
let bypurpose =
|
|
96
|
+
List.find_opt (fun field -> Some "PASSWORD" = Json.oasstr (Json.dig field [ "purpose" ])) fields
|
|
97
|
+
in
|
|
98
|
+
|
|
99
|
+
(match bypurpose with
|
|
100
|
+
| Some field -> Json.otext (Json.dig field [ "value" ])
|
|
101
|
+
| None -> (
|
|
102
|
+
match
|
|
103
|
+
List.find_opt (fun field -> Some "value" = Json.oasstr (Json.dig field [ "label" ])) fields
|
|
104
|
+
with
|
|
105
|
+
| Some field -> Json.otext (Json.dig field [ "value" ])
|
|
106
|
+
| None -> None)));
|
|
107
|
+
describe = (fun () -> "onepassword:" ^ vault);
|
|
108
|
+
}
|
|
109
|
+
|
|
110
|
+
let plugin () : Defs.definition =
|
|
111
|
+
providerplugin "onepassword" (fun spec ->
|
|
112
|
+
onepassword_provider spec.addr spec.token spec.vault)
|