@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.
Files changed (304) hide show
  1. package/bin/voxgig-sdkgen +1 -1
  2. package/package.json +1 -1
  3. package/project/.sdk/model/feature/secrets.aon +330 -0
  4. package/project/.sdk/model/target/c.aon +15 -2
  5. package/project/.sdk/model/target/cpp.aon +18 -0
  6. package/project/.sdk/model/target/lua.aon +17 -0
  7. package/project/.sdk/model/target/ocaml.aon +48 -5
  8. package/project/.sdk/model/target/zig.aon +30 -4
  9. package/project/.sdk/src/cmp/c/Config_c.ts +338 -1
  10. package/project/.sdk/src/cmp/c/Main_c.ts +57 -2
  11. package/project/.sdk/src/cmp/c/Package_c.ts +12 -2
  12. package/project/.sdk/src/cmp/cpp/Config_cpp.ts +324 -2
  13. package/project/.sdk/src/cmp/cpp/Gitignore_cpp.ts +2 -0
  14. package/project/.sdk/src/cmp/cpp/Main_cpp.ts +62 -4
  15. package/project/.sdk/src/cmp/cpp/Package_cpp.ts +10 -0
  16. package/project/.sdk/src/cmp/lua/Config_lua.ts +88 -0
  17. package/project/.sdk/src/cmp/lua/Gitignore_lua.ts +4 -0
  18. package/project/.sdk/src/cmp/lua/Main_lua.ts +93 -3
  19. package/project/.sdk/src/cmp/lua/Package_lua.ts +60 -0
  20. package/project/.sdk/src/cmp/lua/fragment/Main.fragment.lua +10 -0
  21. package/project/.sdk/src/cmp/ocaml/Config_ocaml.ts +183 -5
  22. package/project/.sdk/src/cmp/ocaml/Main_ocaml.ts +160 -3
  23. package/project/.sdk/src/cmp/ocaml/Package_ocaml.ts +25 -1
  24. package/project/.sdk/src/cmp/zig/Config_zig.ts +130 -9
  25. package/project/.sdk/src/cmp/zig/Main_zig.ts +208 -4
  26. package/project/.sdk/{tm/zig/build.zig → src/cmp/zig/fragment/Build.fragment.zig} +7 -0
  27. package/project/.sdk/src/cmp/zig/fragment/Main.fragment.zig +25 -0
  28. package/project/.sdk/{tm/zig/root.zig → src/cmp/zig/fragment/Root.fragment.zig} +9 -0
  29. package/project/.sdk/tm/c/Makefile +58 -9
  30. package/project/.sdk/tm/c/core/sdk.h +10 -0
  31. package/project/.sdk/tm/c/feature/secrets/plugin/capability.c +133 -0
  32. package/project/.sdk/tm/c/feature/secrets/plugin/capability.h +39 -0
  33. package/project/.sdk/tm/c/feature/secrets/plugin/catalog.c +83 -0
  34. package/project/.sdk/tm/c/feature/secrets/plugin/catalog.h +48 -0
  35. package/project/.sdk/tm/c/feature/secrets/plugin/config.c +413 -0
  36. package/project/.sdk/tm/c/feature/secrets/plugin/config.h +24 -0
  37. package/project/.sdk/tm/c/feature/secrets/plugin/depend.c +264 -0
  38. package/project/.sdk/tm/c/feature/secrets/plugin/depend.h +29 -0
  39. package/project/.sdk/tm/c/feature/secrets/plugin/env.c +220 -0
  40. package/project/.sdk/tm/c/feature/secrets/plugin/env.h +19 -0
  41. package/project/.sdk/tm/c/feature/secrets/plugin/export.c +97 -0
  42. package/project/.sdk/tm/c/feature/secrets/plugin/export.h +19 -0
  43. package/project/.sdk/tm/c/feature/secrets/plugin/graph.c +237 -0
  44. package/project/.sdk/tm/c/feature/secrets/plugin/graph.h +17 -0
  45. package/project/.sdk/tm/c/feature/secrets/plugin/host.c +1494 -0
  46. package/project/.sdk/tm/c/feature/secrets/plugin/host.h +135 -0
  47. package/project/.sdk/tm/c/feature/secrets/plugin/order.c +288 -0
  48. package/project/.sdk/tm/c/feature/secrets/plugin/order.h +18 -0
  49. package/project/.sdk/tm/c/feature/secrets/plugin/point.c +141 -0
  50. package/project/.sdk/tm/c/feature/secrets/plugin/point.h +80 -0
  51. package/project/.sdk/tm/c/feature/secrets/plugin/ref.c +170 -0
  52. package/project/.sdk/tm/c/feature/secrets/plugin/ref.h +52 -0
  53. package/project/.sdk/tm/c/feature/secrets/plugin/resolve.c +98 -0
  54. package/project/.sdk/tm/c/feature/secrets/plugin/resolve.h +18 -0
  55. package/project/.sdk/tm/c/feature/secrets/plugin/types.c +150 -0
  56. package/project/.sdk/tm/c/feature/secrets/plugin/types.h +104 -0
  57. package/project/.sdk/tm/c/feature/secrets/plugin/value.c +649 -0
  58. package/project/.sdk/tm/c/feature/secrets/plugin/value.h +135 -0
  59. package/project/.sdk/tm/c/feature/secrets/plugin/version.c +151 -0
  60. package/project/.sdk/tm/c/feature/secrets/plugin/version.h +34 -0
  61. package/project/.sdk/tm/c/feature/secrets/plugins/aws.c +281 -0
  62. package/project/.sdk/tm/c/feature/secrets/plugins/azuresecrets.c +207 -0
  63. package/project/.sdk/tm/c/feature/secrets/plugins/boru.c +164 -0
  64. package/project/.sdk/tm/c/feature/secrets/plugins/clock.c +75 -0
  65. package/project/.sdk/tm/c/feature/secrets/plugins/doppler.c +141 -0
  66. package/project/.sdk/tm/c/feature/secrets/plugins/encode.c +144 -0
  67. package/project/.sdk/tm/c/feature/secrets/plugins/gcpsecrets.c +177 -0
  68. package/project/.sdk/tm/c/feature/secrets/plugins/hashicorp.c +239 -0
  69. package/project/.sdk/tm/c/feature/secrets/plugins/httpjson.c +599 -0
  70. package/project/.sdk/tm/c/feature/secrets/plugins/infisical.c +165 -0
  71. package/project/.sdk/tm/c/feature/secrets/plugins/onepassword.c +194 -0
  72. package/project/.sdk/tm/c/feature/secrets/plugins/proc.c +233 -0
  73. package/project/.sdk/tm/c/feature/secrets/plugins/secretspec.c +125 -0
  74. package/project/.sdk/tm/c/feature/secrets/plugins/sekretoplugins.h +125 -0
  75. package/project/.sdk/tm/c/feature/secrets/plugins/sha256.c +270 -0
  76. package/project/.sdk/tm/c/feature/secrets/plugins/sigv4.c +382 -0
  77. package/project/.sdk/tm/c/feature/secrets/plugins/support.h +153 -0
  78. package/project/.sdk/tm/c/feature/secrets/plugins/tls.c +420 -0
  79. package/project/.sdk/tm/c/feature/secrets/sekreto/internal.h +86 -0
  80. package/project/.sdk/tm/c/feature/secrets/sekreto/json.c +721 -0
  81. package/project/.sdk/tm/c/feature/secrets/sekreto/providers.c +813 -0
  82. package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.c +944 -0
  83. package/project/.sdk/tm/c/feature/secrets/sekreto/sekreto.h +490 -0
  84. package/project/.sdk/tm/c/feature/secrets/sekreto/util.c +442 -0
  85. package/project/.sdk/tm/c/feature/secrets.c +797 -0
  86. package/project/.sdk/tm/c/feature/secrets.h +46 -0
  87. package/project/.sdk/tm/c/src/feature/secrets/.gitkeep +0 -0
  88. package/project/.sdk/tm/c/tests/feature/secrets/secrets_test.c +802 -0
  89. package/project/.sdk/tm/clojure/feature/secrets/sdk/feature/secrets.clj +38 -11
  90. package/project/.sdk/tm/clojure/test/sdk/test/feature/secrets.clj +40 -6
  91. package/project/.sdk/tm/cpp/Makefile +48 -4
  92. package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.cpp +121 -0
  93. package/project/.sdk/tm/cpp/feature/secrets/plugin/capability.hpp +41 -0
  94. package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.cpp +60 -0
  95. package/project/.sdk/tm/cpp/feature/secrets/plugin/catalog.hpp +66 -0
  96. package/project/.sdk/tm/cpp/feature/secrets/plugin/config.cpp +376 -0
  97. package/project/.sdk/tm/cpp/feature/secrets/plugin/config.hpp +29 -0
  98. package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.cpp +230 -0
  99. package/project/.sdk/tm/cpp/feature/secrets/plugin/depend.hpp +31 -0
  100. package/project/.sdk/tm/cpp/feature/secrets/plugin/env.cpp +205 -0
  101. package/project/.sdk/tm/cpp/feature/secrets/plugin/env.hpp +25 -0
  102. package/project/.sdk/tm/cpp/feature/secrets/plugin/export.cpp +84 -0
  103. package/project/.sdk/tm/cpp/feature/secrets/plugin/export.hpp +24 -0
  104. package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.cpp +222 -0
  105. package/project/.sdk/tm/cpp/feature/secrets/plugin/graph.hpp +21 -0
  106. package/project/.sdk/tm/cpp/feature/secrets/plugin/host.cpp +1200 -0
  107. package/project/.sdk/tm/cpp/feature/secrets/plugin/host.hpp +250 -0
  108. package/project/.sdk/tm/cpp/feature/secrets/plugin/order.cpp +250 -0
  109. package/project/.sdk/tm/cpp/feature/secrets/plugin/order.hpp +22 -0
  110. package/project/.sdk/tm/cpp/feature/secrets/plugin/point.cpp +110 -0
  111. package/project/.sdk/tm/cpp/feature/secrets/plugin/point.hpp +79 -0
  112. package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.cpp +136 -0
  113. package/project/.sdk/tm/cpp/feature/secrets/plugin/ref.hpp +60 -0
  114. package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.cpp +82 -0
  115. package/project/.sdk/tm/cpp/feature/secrets/plugin/resolve.hpp +25 -0
  116. package/project/.sdk/tm/cpp/feature/secrets/plugin/types.cpp +90 -0
  117. package/project/.sdk/tm/cpp/feature/secrets/plugin/types.hpp +65 -0
  118. package/project/.sdk/tm/cpp/feature/secrets/plugin/value.cpp +491 -0
  119. package/project/.sdk/tm/cpp/feature/secrets/plugin/value.hpp +120 -0
  120. package/project/.sdk/tm/cpp/feature/secrets/plugin/version.cpp +143 -0
  121. package/project/.sdk/tm/cpp/feature/secrets/plugin/version.hpp +36 -0
  122. package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.cpp +248 -0
  123. package/project/.sdk/tm/cpp/feature/secrets/plugins/Aws.hpp +30 -0
  124. package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.cpp +149 -0
  125. package/project/.sdk/tm/cpp/feature/secrets/plugins/Azuresecrets.hpp +23 -0
  126. package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.cpp +117 -0
  127. package/project/.sdk/tm/cpp/feature/secrets/plugins/Boru.hpp +27 -0
  128. package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.cpp +180 -0
  129. package/project/.sdk/tm/cpp/feature/secrets/plugins/Crypto.hpp +52 -0
  130. package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.cpp +87 -0
  131. package/project/.sdk/tm/cpp/feature/secrets/plugins/Doppler.hpp +23 -0
  132. package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.cpp +121 -0
  133. package/project/.sdk/tm/cpp/feature/secrets/plugins/Gcpsecrets.hpp +23 -0
  134. package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.cpp +153 -0
  135. package/project/.sdk/tm/cpp/feature/secrets/plugins/Hashicorp.hpp +23 -0
  136. package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.cpp +666 -0
  137. package/project/.sdk/tm/cpp/feature/secrets/plugins/Httpjson.hpp +160 -0
  138. package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.cpp +123 -0
  139. package/project/.sdk/tm/cpp/feature/secrets/plugins/Infisical.hpp +23 -0
  140. package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.cpp +125 -0
  141. package/project/.sdk/tm/cpp/feature/secrets/plugins/Onepassword.hpp +23 -0
  142. package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.cpp +223 -0
  143. package/project/.sdk/tm/cpp/feature/secrets/plugins/Proc.hpp +47 -0
  144. package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.cpp +104 -0
  145. package/project/.sdk/tm/cpp/feature/secrets/plugins/Secretspec.hpp +27 -0
  146. package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.cpp +242 -0
  147. package/project/.sdk/tm/cpp/feature/secrets/plugins/Sigv4.hpp +58 -0
  148. package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.cpp +260 -0
  149. package/project/.sdk/tm/cpp/feature/secrets/plugins/Tls.hpp +47 -0
  150. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.cpp +476 -0
  151. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Json.hpp +89 -0
  152. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.cpp +312 -0
  153. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Provider.hpp +263 -0
  154. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.cpp +354 -0
  155. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Providers.hpp +111 -0
  156. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.cpp +613 -0
  157. package/project/.sdk/tm/cpp/feature/secrets/sekreto/Sekreto.hpp +227 -0
  158. package/project/.sdk/tm/cpp/feature/secrets.hpp +745 -0
  159. package/project/.sdk/tm/cpp/src/feature/secrets/.gitkeep +0 -0
  160. package/project/.sdk/tm/cpp/test/feature/secrets/secrets_test.cpp +808 -0
  161. package/project/.sdk/tm/csharp/feature/SecretsFeature.cs +34 -8
  162. package/project/.sdk/tm/csharp/test/feature/secrets/SecretsFeatureTest.cs +85 -0
  163. package/project/.sdk/tm/elixir/lib/projectname/feature/secrets.ex +17 -2
  164. package/project/.sdk/tm/elixir/test/feature/secrets/secrets_test.exs +41 -0
  165. package/project/.sdk/tm/go/feature/secrets_feature.go +32 -10
  166. package/project/.sdk/tm/go/test/feature/secrets/secrets_feature_test.go +116 -0
  167. package/project/.sdk/tm/java/feature/SecretsFeature.java +33 -8
  168. package/project/.sdk/tm/java/test/feature/secrets/SecretsFeatureTest.java +64 -0
  169. package/project/.sdk/tm/js/src/feature/secrets/SecretsFeature.js +34 -11
  170. package/project/.sdk/tm/js/test/feature/secrets/Secrets.test.js +73 -0
  171. package/project/.sdk/tm/kotlin/feature/SecretsFeature.kt +32 -7
  172. package/project/.sdk/tm/kotlin/test/feature/secrets/SecretsTest.kt +69 -0
  173. package/project/.sdk/tm/lua/Makefile +15 -4
  174. package/project/.sdk/tm/lua/feature/secrets/native/sekretonet.c +806 -0
  175. package/project/.sdk/tm/lua/feature/secrets/plugin/capability.lua +135 -0
  176. package/project/.sdk/tm/lua/feature/secrets/plugin/catalog.lua +63 -0
  177. package/project/.sdk/tm/lua/feature/secrets/plugin/config.lua +361 -0
  178. package/project/.sdk/tm/lua/feature/secrets/plugin/depend.lua +232 -0
  179. package/project/.sdk/tm/lua/feature/secrets/plugin/env.lua +168 -0
  180. package/project/.sdk/tm/lua/feature/secrets/plugin/export.lua +66 -0
  181. package/project/.sdk/tm/lua/feature/secrets/plugin/graph.lua +194 -0
  182. package/project/.sdk/tm/lua/feature/secrets/plugin/host.lua +1190 -0
  183. package/project/.sdk/tm/lua/feature/secrets/plugin/json.lua +169 -0
  184. package/project/.sdk/tm/lua/feature/secrets/plugin/order.lua +207 -0
  185. package/project/.sdk/tm/lua/feature/secrets/plugin/point.lua +106 -0
  186. package/project/.sdk/tm/lua/feature/secrets/plugin/ref.lua +115 -0
  187. package/project/.sdk/tm/lua/feature/secrets/plugin/resolve.lua +78 -0
  188. package/project/.sdk/tm/lua/feature/secrets/plugin/types.lua +275 -0
  189. package/project/.sdk/tm/lua/feature/secrets/plugin/version.lua +131 -0
  190. package/project/.sdk/tm/lua/feature/secrets/plugin.lua +76 -0
  191. package/project/.sdk/tm/lua/feature/secrets/sekreto/addr.lua +124 -0
  192. package/project/.sdk/tm/lua/feature/secrets/sekreto/err.lua +47 -0
  193. package/project/.sdk/tm/lua/feature/secrets/sekreto/name.lua +315 -0
  194. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/aws.lua +228 -0
  195. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/azuresecrets.lua +137 -0
  196. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/boru.lua +124 -0
  197. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/crypto.lua +212 -0
  198. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/doppler.lua +89 -0
  199. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/gcpsecrets.lua +129 -0
  200. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/hashicorp.lua +154 -0
  201. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/httpjson.lua +248 -0
  202. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/infisical.lua +113 -0
  203. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/json.lua +449 -0
  204. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/net.lua +198 -0
  205. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/onepassword.lua +126 -0
  206. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/secretspec.lua +93 -0
  207. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/sigv4.lua +269 -0
  208. package/project/.sdk/tm/lua/feature/secrets/sekreto/plugins/support.lua +146 -0
  209. package/project/.sdk/tm/lua/feature/secrets/sekreto/providers.lua +346 -0
  210. package/project/.sdk/tm/lua/feature/secrets/sekreto.lua +479 -0
  211. package/project/.sdk/tm/lua/feature/secrets_feature.lua +690 -0
  212. package/project/.sdk/tm/lua/src/feature/secrets/.gitkeep +0 -0
  213. package/project/.sdk/tm/lua/test/extend_test.lua +105 -0
  214. package/project/.sdk/tm/lua/test/feature/secrets/secrets_feature_test.lua +862 -0
  215. package/project/.sdk/tm/ocaml/Makefile +52 -8
  216. package/project/.sdk/tm/ocaml/feature/secrets/plugin/capability.ml +106 -0
  217. package/project/.sdk/tm/ocaml/feature/secrets/plugin/catalog.ml +43 -0
  218. package/project/.sdk/tm/ocaml/feature/secrets/plugin/config.ml +349 -0
  219. package/project/.sdk/tm/ocaml/feature/secrets/plugin/defs.ml +143 -0
  220. package/project/.sdk/tm/ocaml/feature/secrets/plugin/depend.ml +217 -0
  221. package/project/.sdk/tm/ocaml/feature/secrets/plugin/env.ml +197 -0
  222. package/project/.sdk/tm/ocaml/feature/secrets/plugin/export.ml +89 -0
  223. package/project/.sdk/tm/ocaml/feature/secrets/plugin/graph.ml +227 -0
  224. package/project/.sdk/tm/ocaml/feature/secrets/plugin/host.ml +1112 -0
  225. package/project/.sdk/tm/ocaml/feature/secrets/plugin/order.ml +202 -0
  226. package/project/.sdk/tm/ocaml/feature/secrets/plugin/point.ml +138 -0
  227. package/project/.sdk/tm/ocaml/feature/secrets/plugin/ref.ml +126 -0
  228. package/project/.sdk/tm/ocaml/feature/secrets/plugin/resolve.ml +62 -0
  229. package/project/.sdk/tm/ocaml/feature/secrets/plugin/types.ml +97 -0
  230. package/project/.sdk/tm/ocaml/feature/secrets/plugin/value.ml +387 -0
  231. package/project/.sdk/tm/ocaml/feature/secrets/plugin/version.ml +139 -0
  232. package/project/.sdk/tm/ocaml/feature/secrets/plugins/aws.ml +171 -0
  233. package/project/.sdk/tm/ocaml/feature/secrets/plugins/azuresecrets.ml +116 -0
  234. package/project/.sdk/tm/ocaml/feature/secrets/plugins/boru.ml +95 -0
  235. package/project/.sdk/tm/ocaml/feature/secrets/plugins/crypto.ml +149 -0
  236. package/project/.sdk/tm/ocaml/feature/secrets/plugins/doppler.ml +61 -0
  237. package/project/.sdk/tm/ocaml/feature/secrets/plugins/gcpsecrets.ml +93 -0
  238. package/project/.sdk/tm/ocaml/feature/secrets/plugins/hashicorp.ml +120 -0
  239. package/project/.sdk/tm/ocaml/feature/secrets/plugins/http.ml +421 -0
  240. package/project/.sdk/tm/ocaml/feature/secrets/plugins/httpjson.ml +66 -0
  241. package/project/.sdk/tm/ocaml/feature/secrets/plugins/infisical.ml +85 -0
  242. package/project/.sdk/tm/ocaml/feature/secrets/plugins/onepassword.ml +112 -0
  243. package/project/.sdk/tm/ocaml/feature/secrets/plugins/runcmd.ml +97 -0
  244. package/project/.sdk/tm/ocaml/feature/secrets/plugins/secretspec.ml +68 -0
  245. package/project/.sdk/tm/ocaml/feature/secrets/plugins/sigv4.ml +259 -0
  246. package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls.ml +44 -0
  247. package/project/.sdk/tm/ocaml/feature/secrets/plugins/tls_stubs.c +358 -0
  248. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/json.ml +376 -0
  249. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/provider.ml +647 -0
  250. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/secret.ml +299 -0
  251. package/project/.sdk/tm/ocaml/feature/secrets/sekreto/sekreto.ml +347 -0
  252. package/project/.sdk/tm/ocaml/feature/secrets_feature.ml +453 -0
  253. package/project/.sdk/tm/ocaml/src/feature/secrets/.gitkeep +0 -0
  254. package/project/.sdk/tm/ocaml/test/feature/secrets/t_secrets.ml +670 -0
  255. package/project/.sdk/tm/perl/feature/secrets_feature.pm +33 -12
  256. package/project/.sdk/tm/perl/t/feature/secrets/secrets.t +47 -0
  257. package/project/.sdk/tm/php/feature/SecretsFeature.php +30 -6
  258. package/project/.sdk/tm/php/test/feature/secrets/SecretsTest.php +98 -0
  259. package/project/.sdk/tm/py/pkg/feature/secrets_feature.py +28 -6
  260. package/project/.sdk/tm/py/test/feature/secrets/test_secrets.py +114 -0
  261. package/project/.sdk/tm/rb/feature/secrets_feature.rb +28 -6
  262. package/project/.sdk/tm/rb/test/feature/secrets/secrets_feature_test.rb +93 -0
  263. package/project/.sdk/tm/rust/feature/secrets.rs +33 -10
  264. package/project/.sdk/tm/rust/tests/feature/secrets/main.rs +96 -0
  265. package/project/.sdk/tm/scala/feature/SecretsFeature.scala +29 -7
  266. package/project/.sdk/tm/scala/sdktest/feature/secrets/SecretsTestMain.scala +71 -0
  267. package/project/.sdk/tm/ts/src/feature/secrets/SecretsFeature.ts +35 -12
  268. package/project/.sdk/tm/ts/test/feature/secrets/Secrets.test.ts +73 -0
  269. package/project/.sdk/tm/zig/feature/secrets/plugin/capability.zig +137 -0
  270. package/project/.sdk/tm/zig/feature/secrets/plugin/catalog.zig +90 -0
  271. package/project/.sdk/tm/zig/feature/secrets/plugin/config.zig +346 -0
  272. package/project/.sdk/tm/zig/feature/secrets/plugin/depend.zig +244 -0
  273. package/project/.sdk/tm/zig/feature/secrets/plugin/env.zig +201 -0
  274. package/project/.sdk/tm/zig/feature/secrets/plugin/export.zig +83 -0
  275. package/project/.sdk/tm/zig/feature/secrets/plugin/graph.zig +212 -0
  276. package/project/.sdk/tm/zig/feature/secrets/plugin/host.zig +1224 -0
  277. package/project/.sdk/tm/zig/feature/secrets/plugin/inst.zig +126 -0
  278. package/project/.sdk/tm/zig/feature/secrets/plugin/order.zig +228 -0
  279. package/project/.sdk/tm/zig/feature/secrets/plugin/plugin.zig +34 -0
  280. package/project/.sdk/tm/zig/feature/secrets/plugin/point.zig +166 -0
  281. package/project/.sdk/tm/zig/feature/secrets/plugin/ref.zig +147 -0
  282. package/project/.sdk/tm/zig/feature/secrets/plugin/resolve.zig +74 -0
  283. package/project/.sdk/tm/zig/feature/secrets/plugin/types.zig +140 -0
  284. package/project/.sdk/tm/zig/feature/secrets/plugin/value.zig +662 -0
  285. package/project/.sdk/tm/zig/feature/secrets/plugin/version.zig +139 -0
  286. package/project/.sdk/tm/zig/feature/secrets/plugins/aws.zig +294 -0
  287. package/project/.sdk/tm/zig/feature/secrets/plugins/azuresecrets.zig +222 -0
  288. package/project/.sdk/tm/zig/feature/secrets/plugins/boru.zig +188 -0
  289. package/project/.sdk/tm/zig/feature/secrets/plugins/doppler.zig +135 -0
  290. package/project/.sdk/tm/zig/feature/secrets/plugins/gcpsecrets.zig +170 -0
  291. package/project/.sdk/tm/zig/feature/secrets/plugins/hashicorp.zig +242 -0
  292. package/project/.sdk/tm/zig/feature/secrets/plugins/httpjson.zig +535 -0
  293. package/project/.sdk/tm/zig/feature/secrets/plugins/infisical.zig +167 -0
  294. package/project/.sdk/tm/zig/feature/secrets/plugins/onepassword.zig +202 -0
  295. package/project/.sdk/tm/zig/feature/secrets/plugins/secretspec.zig +160 -0
  296. package/project/.sdk/tm/zig/feature/secrets/plugins/sigv4.zig +336 -0
  297. package/project/.sdk/tm/zig/feature/secrets/sekreto/addr.zig +148 -0
  298. package/project/.sdk/tm/zig/feature/secrets/sekreto/builtins.zig +259 -0
  299. package/project/.sdk/tm/zig/feature/secrets/sekreto/provider.zig +440 -0
  300. package/project/.sdk/tm/zig/feature/secrets/sekreto/sekreto.zig +944 -0
  301. package/project/.sdk/tm/zig/feature/secrets.zig +854 -0
  302. package/project/.sdk/tm/zig/src/feature/secrets/.gitkeep +0 -0
  303. package/project/.sdk/tm/zig/test/feature/secrets/secrets_test.zig +891 -0
  304. package/project/sdkgen-package.json +1 -1
@@ -0,0 +1,670 @@
1
+ (* Behavioural tests for the secrets feature (vendored @voxgig/sekreto).
2
+ *
3
+ * The contract under test: the `apikey` OPTION keeps its exact old meaning
4
+ * and always wins, because the feature seats it FIRST in the provider chain
5
+ * (a `memory` store named `options`) - explicit-beats-lookup falls out of
6
+ * sekreto's first-hit rule rather than from special-case logic. With the
7
+ * feature inactive nothing changes at all. With it active and the option
8
+ * unset, the chain supplies the credential instead.
9
+ *
10
+ * THE SHAPE OF EVERY FAIL-CLOSED CASE HERE, and why. A test that passes
11
+ * whether or not the thing it names is present is worthless, so:
12
+ * - the client is LIVE (Sdk_client.make), so `options.system.fetch` really
13
+ * is the transport and the feature's wrapper sits above it - never the
14
+ * test-mode mock, which replaces the fetcher and hides the seam;
15
+ * - every assertion reads the authorization header the RECORDER received,
16
+ * never the options map, which this feature never writes;
17
+ * - a refusal must carry the PROVIDER'S OWN message (sekreto's wording),
18
+ * not any error;
19
+ * - beside every refusal is a CONTROL leg: the same construction with a
20
+ * working provider reaches the same recorder exactly once - so a zero
21
+ * on the refused leg means REFUSED, not UNWIRED.
22
+ * Delete the gate in feature/secrets_feature.ml and these go RED.
23
+ *
24
+ * This file lives in the test/feature/ container on purpose: `target add`
25
+ * trims it, along with the feature source and the vendored trees, for a
26
+ * project whose model does not select `secrets`; feature/secrets/feature.mk lists it, so
27
+ * it is linked into run_sdk_test whenever the feature is. It prints
28
+ * `feature.secrets: ran N check(s)` from EXECUTIONS, which the generator's
29
+ * own lane requires - a suite trimmed to nothing cannot pass by exiting
30
+ * zero. *)
31
+
32
+ open Voxgig_struct
33
+ open Sdk_types
34
+ open Sdk_helpers
35
+ open Testutil
36
+
37
+ (* Executed-case count, for the line the lane reads. *)
38
+ let ran = ref 0
39
+ let test (name : string) (f : unit -> unit) : unit =
40
+ incr ran;
41
+ Testutil.test ("secrets." ^ name) f
42
+
43
+ let envprefix = "PROJECTENV_TEST_SECRETS_"
44
+
45
+ (* ---------------------------------------------------------------------- *)
46
+ (* the recorder: a system.fetch that remembers what reached it *)
47
+ (* ---------------------------------------------------------------------- *)
48
+
49
+ let ok200 (data : value) : value =
50
+ jo [("status", Num 200.); ("statusText", Str "OK"); ("headers", empty_map ());
51
+ ("body", Str "not-used"); ("json", json_thunk data)]
52
+
53
+ let status_res (status : int) (data : value) : value =
54
+ jo [("status", vint_of status); ("statusText", Str (if status < 400 then "OK" else "ERR"));
55
+ ("headers", empty_map ()); ("body", Str "not-used"); ("json", json_thunk data)]
56
+
57
+ type recorder = {
58
+ calls : value list ref;
59
+ (* (call number, url, fetchdef) -> the transport-shaped response *)
60
+ mutable reply : (int -> string -> value -> value) option;
61
+ }
62
+
63
+ let is_token (url : string) : bool =
64
+ let suffix = "/auth/token" in
65
+ let lu = String.length url and ls = String.length suffix in
66
+ lu >= ls && String.sub url (lu - ls) ls = suffix
67
+
68
+ let recorder () : recorder * value =
69
+ let r = { calls = ref []; reply = None } in
70
+ let fetch = Func (fun _ args _ _ ->
71
+ let (url, fd) = match args with
72
+ | List l -> (match !l with
73
+ | Str u :: fd :: _ -> (u, fd)
74
+ | Str u :: [] -> (u, Noval)
75
+ | _ -> ("", Noval))
76
+ | _ -> ("", Noval) in
77
+ r.calls := !(r.calls) @ [jo [("url", Str url); ("fetchdef", fd)]];
78
+ match r.reply with
79
+ | Some f -> f (List.length !(r.calls)) url fd
80
+ | None -> ok200 (jo [("id", Str "r01")])) in
81
+ (r, fetch)
82
+
83
+ (* The API calls (not the token endpoint) the recorder saw, in order. *)
84
+ let api_calls (r : recorder) : value list =
85
+ List.filter (fun c -> not (is_token (match getp c "url" with Str u -> u | _ -> ""))) !(r.calls)
86
+
87
+ let token_calls (r : recorder) : value list =
88
+ List.filter (fun c -> is_token (match getp c "url" with Str u -> u | _ -> "")) !(r.calls)
89
+
90
+ (* The authorization header the i-th API call carried, or Noval. *)
91
+ let auth_of (r : recorder) (i : int) : value =
92
+ match List.nth_opt (api_calls r) i with
93
+ | Some c -> (match getp (getp c "fetchdef") "headers" with
94
+ | Map _ as h -> Sdk_features.header_ci h "authorization"
95
+ | _ -> Noval)
96
+ | None -> Noval
97
+
98
+ (* The Authorization header carries the SPEC's credential prefix, which a
99
+ * TEMPLATE cannot know - so assert on the CREDENTIAL and let the prefix be
100
+ * whatever this SDK's API declares. *)
101
+ let credential_is (header : value) (token : string) : bool =
102
+ match header with
103
+ | Str s -> s = token || Sdk_features.ends_with s (" " ^ token)
104
+ | _ -> false
105
+
106
+ let absent (header : value) : bool = is_nullish header
107
+
108
+ (* ---------------------------------------------------------------------- *)
109
+ (* clients and paths *)
110
+ (* ---------------------------------------------------------------------- *)
111
+
112
+ (* A LIVE client with the secrets feature active and the recorder as its
113
+ * transport. `sdkopts` are extra top-level options (apikey, auth, name...). *)
114
+ let live ?(sdkopts : (string * value) list = []) ?(base = "http://secrets.test/api")
115
+ (fetch : value) (fopts : (string * value) list) : sdk_client =
116
+ Sdk_client.make (jo ([
117
+ ("base", Str base);
118
+ ("system", jo [("fetch", fetch)]);
119
+ ("feature", jo [("secrets", jo (("active", Bool true) :: fopts))]);
120
+ ] @ sdkopts))
121
+
122
+ (* The same construction with the feature declared INACTIVE. *)
123
+ let inactive ?(sdkopts : (string * value) list = []) (fetch : value) : sdk_client =
124
+ Sdk_client.make (jo ([
125
+ ("base", Str "http://secrets.test/api");
126
+ ("system", jo [("fetch", fetch)]);
127
+ ("feature", jo [("secrets", jo [("active", Bool false)])]);
128
+ ] @ sdkopts))
129
+
130
+ let direct (client : sdk_client) : value =
131
+ Sdk_client.direct client (jo [("path", Str "/thing"); ("method", Str "GET")])
132
+
133
+ let graphql (client : sdk_client) : value =
134
+ Sdk_client.graphql client "{ thing { id } }" Noval Noval
135
+
136
+ let res_ok (res : value) : bool = getp res "ok" = Bool true
137
+
138
+ let res_err (res : value) : string =
139
+ match getp res "err" with
140
+ | Str s -> s
141
+ | Map _ as m -> (match getp m "message" with Str s -> s | _ -> stringify m)
142
+ | _ -> ""
143
+
144
+ let contains (hay : string) (needle : string) : bool =
145
+ let lh = String.length hay and ln = String.length needle in
146
+ let rec go i = i + ln <= lh && (String.sub hay i ln = needle || go (i + 1)) in
147
+ ln = 0 || go 0
148
+
149
+ (* THE ENTITY PIPELINE, through the entities this SDK generated. This file
150
+ * is a template and knows no project's entity names, so they are read from
151
+ * the generated config and reached through Sdk_client.entity (the by-name
152
+ * accessor). Real ops are driven until one reaches the recorder or the
153
+ * chain refuses one; an op the API does not define fails BEFORE the
154
+ * transport, which is why several may need driving. *)
155
+ let entity_names () : string list =
156
+ match getp (Sdk_config.make_config ()) "entity" with
157
+ | Map _ as m -> keysof m
158
+ | _ -> []
159
+
160
+ (* Drive ops until one request reached the recorder. *)
161
+ let drive_entity (client : sdk_client) (r : recorder) : (unit, string) Stdlib.result =
162
+ let before = List.length (api_calls r) in
163
+ let out = ref (Error "") in
164
+ (* A refused op raises before the recorder sees anything; a working one
165
+ * reaches it. Either way the first op that consulted the chain settles
166
+ * it, so ops are driven until the recorder grew or an op reported. *)
167
+ let rec go names =
168
+ match names with
169
+ | [] -> ()
170
+ | name :: rest ->
171
+ (match Sdk_client.entity client name Noval with
172
+ | None -> go rest
173
+ | Some ent ->
174
+ let rec ops = function
175
+ | [] -> go rest
176
+ | opname :: more ->
177
+ (match (match opname with
178
+ | "list" -> ignore (ent.e_list (empty_map ()) Noval)
179
+ | _ -> ignore (ent.e_load (jo [("id", Str "id01")]) Noval)) with
180
+ | () ->
181
+ out := Ok ();
182
+ if before < List.length (api_calls r) then () else ops more
183
+ | exception Sdk_error_exc e ->
184
+ (* An op the entity does not define fails before the chain
185
+ * is consulted: keep going. Anything else is the answer. *)
186
+ if e.err_code = "unsupported_op" then ops more
187
+ else (out := Error e.err_msg)
188
+ | exception e -> out := Error (Printexc.to_string e))
189
+ in
190
+ ops ["list"; "load"])
191
+ in
192
+ go (entity_names ());
193
+ !out
194
+
195
+ (* Custom (Func) providers: asked the secret name, answer a string, a miss
196
+ * (Null) or raise. `asked` counts lookups. *)
197
+ let custom (answer : int -> value) : value * int ref =
198
+ let asked = ref 0 in
199
+ let fn = vfunc1 (fun _name -> incr asked; answer !asked) in
200
+ (fn, asked)
201
+
202
+ let working (v : string) : value = fst (custom (fun _ -> Str v))
203
+
204
+ let broken (message : string) : value =
205
+ vfunc1 (fun _ -> Secret.fail message)
206
+
207
+ let memory ?(name = "options2") (values : (string * value) list) : value =
208
+ jo [("kind", Str "memory"); ("name", Str name); ("values", jo values)]
209
+
210
+ (* ---------------------------------------------------------------------- *)
211
+ (* inactive *)
212
+ (* ---------------------------------------------------------------------- *)
213
+
214
+ let () =
215
+ test "inactive.apikey_option_behaves_as_before" (fun () ->
216
+ let (r, fetch) = recorder () in
217
+ let client = inactive ~sdkopts:[("apikey", Str "OPTKEY01")] fetch in
218
+ check "ok" (res_ok (direct client));
219
+ check_int "one call" (List.length (api_calls r)) 1;
220
+ check "carries OPTKEY01" (credential_is (auth_of r 0) "OPTKEY01"));
221
+
222
+ test "inactive.no_apikey_no_header" (fun () ->
223
+ let (r, fetch) = recorder () in
224
+ let client = inactive fetch in
225
+ check "ok" (res_ok (direct client));
226
+ check "no header" (absent (auth_of r 0)));
227
+
228
+ (* ---------------------------------------------------------------------- *)
229
+ (* the chain *)
230
+ (* ---------------------------------------------------------------------- *)
231
+
232
+ Unix.putenv (envprefix ^ "APIKEY") "ENVKEY01";
233
+
234
+ test "chain.apikey_option_still_wins" (fun () ->
235
+ let (r, fetch) = recorder () in
236
+ let client = live ~sdkopts:[("apikey", Str "OPTKEY01")] fetch
237
+ [("providers", ja [jo [("kind", Str "env"); ("prefix", Str envprefix)]])] in
238
+ check "ok" (res_ok (direct client));
239
+ check "carries OPTKEY01, not ENVKEY01" (credential_is (auth_of r 0) "OPTKEY01"));
240
+
241
+ test "chain.omitted_apikey_defers_to_the_chain" (fun () ->
242
+ let (r, fetch) = recorder () in
243
+ let client = live fetch
244
+ [("providers", ja [jo [("kind", Str "env"); ("prefix", Str envprefix)]])] in
245
+ check "ok" (res_ok (direct client));
246
+ check "carries ENVKEY01" (credential_is (auth_of r 0) "ENVKEY01"));
247
+
248
+ test "chain.explicitly_empty_apikey_defers_to_the_chain" (fun () ->
249
+ let (r, fetch) = recorder () in
250
+ let client = live ~sdkopts:[("apikey", Str "")] fetch
251
+ [("providers", ja [jo [("kind", Str "env"); ("prefix", Str envprefix)]])] in
252
+ check "ok" (res_ok (direct client));
253
+ check "carries ENVKEY01" (credential_is (auth_of r 0) "ENVKEY01"));
254
+
255
+ test "chain.custom_provider_accepted_verbatim" (fun () ->
256
+ let (r, fetch) = recorder () in
257
+ let names = ref [] in
258
+ let fn = vfunc1 (fun name -> names := !names @ [name]; Str "CUSTOM01") in
259
+ let client = live fetch [("providers", ja [fn])] in
260
+ check "ok" (res_ok (direct client));
261
+ check "carries CUSTOM01" (credential_is (auth_of r 0) "CUSTOM01");
262
+ check "asked for the configured secret name" (!names = [Str "apikey"]));
263
+
264
+ test "chain.custom_provider_asked_for_the_configured_name" (fun () ->
265
+ let (r, fetch) = recorder () in
266
+ let names = ref [] in
267
+ let fn = vfunc1 (fun name -> names := !names @ [name]; Str "CUSTOM02") in
268
+ let client = live fetch [("providers", ja [fn]); ("name", Str "api.token")] in
269
+ check "ok" (res_ok (direct client));
270
+ check "carries CUSTOM02" (credential_is (auth_of r 0) "CUSTOM02");
271
+ check "asked api.token" (!names = [Str "api.token"]));
272
+
273
+ test "chain.miss_everywhere_leaves_the_header_off" (fun () ->
274
+ let (r, fetch) = recorder () in
275
+ let (fn, asked) = custom (fun _ -> Null) in
276
+ let client = live fetch [("providers", ja [fn])] in
277
+ check "ok" (res_ok (direct client));
278
+ check_int "one call" (List.length (api_calls r)) 1;
279
+ check "no header" (absent (auth_of r 0));
280
+ check_int "the chain was asked" !asked 1);
281
+
282
+ test "chain.miss_falls_through_to_the_next_provider" (fun () ->
283
+ let (r, fetch) = recorder () in
284
+ let (fn, _) = custom (fun _ -> Null) in
285
+ let client = live fetch [("providers", ja [fn; memory [("APIKEY", Str "MEM01")]])] in
286
+ check "ok" (res_ok (direct client));
287
+ check "carries MEM01" (credential_is (auth_of r 0) "MEM01"));
288
+
289
+ (* ---------------------------------------------------------------------- *)
290
+ (* fail closed: a provider ERROR never degrades into an unauthenticated *)
291
+ (* request, on every wire path *)
292
+ (* ---------------------------------------------------------------------- *)
293
+
294
+ test "error.direct_is_refused_with_the_providers_message" (fun () ->
295
+ let (r, fetch) = recorder () in
296
+ let client = live fetch [("providers", ja [broken "vault unreachable"])] in
297
+ let res = direct client in
298
+ check "refused" (not (res_ok res));
299
+ check ("carries the provider's own message: " ^ res_err res)
300
+ (contains (res_err res) "vault unreachable");
301
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0;
302
+ (* CONTROL *)
303
+ let (r2, fetch2) = recorder () in
304
+ let ok = live fetch2 [("providers", ja [working "CUSTOM01"])] in
305
+ check "control: the working chain succeeds" (res_ok (direct ok));
306
+ check_int "control: reached the wire once" (List.length (api_calls r2)) 1;
307
+ check "control: with the credential" (credential_is (auth_of r2 0) "CUSTOM01"));
308
+
309
+ test "error.graphql_is_refused_with_the_providers_message" (fun () ->
310
+ let (r, fetch) = recorder () in
311
+ let client = live fetch [("providers", ja [broken "vault unreachable"])] in
312
+ let res = graphql client in
313
+ check "refused" (not (res_ok res));
314
+ check ("carries the provider's own message: " ^ res_err res)
315
+ (contains (res_err res) "vault unreachable");
316
+ check_int "graphql sent nothing" (List.length (api_calls r)) 0;
317
+ let (r2, fetch2) = recorder () in
318
+ let ok = live fetch2 [("providers", ja [working "CUSTOM01"])] in
319
+ check "control: graphql with a working chain succeeds" (res_ok (graphql ok));
320
+ check_int "control: graphql reached the wire once" (List.length (api_calls r2)) 1;
321
+ check "control: graphql carried the credential" (credential_is (auth_of r2 0) "CUSTOM01"));
322
+
323
+ test "error.entity_op_is_refused_with_the_providers_message" (fun () ->
324
+ let (r, fetch) = recorder () in
325
+ let client = live fetch [("providers", ja [broken "vault unreachable"])] in
326
+ (match drive_entity client r with
327
+ | Ok () -> failwith "entity: the op succeeded through a broken chain"
328
+ | Error msg ->
329
+ check ("entity: carries the provider's own message: " ^ msg)
330
+ (contains msg "vault unreachable"));
331
+ check_int "entity: nothing reached the transport" (List.length (api_calls r)) 0;
332
+ let (r2, fetch2) = recorder () in
333
+ let ok = live fetch2 [("providers", ja [working "CUSTOM01"])] in
334
+ (match drive_entity ok r2 with
335
+ | Ok () -> ()
336
+ | Error msg -> failwith ("control: the entity op failed: " ^ msg));
337
+ check_int "control: the entity op reached the transport once" (List.length (api_calls r2)) 1;
338
+ check "control: the entity op carried the credential" (credential_is (auth_of r2 0) "CUSTOM01"));
339
+
340
+ test "error.fails_even_though_a_later_provider_has_the_secret" (fun () ->
341
+ let (r, fetch) = recorder () in
342
+ let client = live fetch
343
+ [("providers", ja [broken "vault unreachable"; memory [("APIKEY", Str "MEM01")]])] in
344
+ let res = direct client in
345
+ check "refused" (not (res_ok res));
346
+ check "the provider's message" (contains (res_err res) "vault unreachable");
347
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
348
+
349
+ test "error.a_broken_store_does_not_poison_the_client" (fun () ->
350
+ let (r, fetch) = recorder () in
351
+ let (fn, _) = custom (fun n -> if n = 1 then Secret.fail "vault unreachable" else Str "LATE01") in
352
+ let client = live fetch [("providers", ja [fn])] in
353
+ check "first op refused" (not (res_ok (direct client)));
354
+ check_int "nothing sent" (List.length (api_calls r)) 0;
355
+ check "second op succeeds" (res_ok (direct client));
356
+ check_int "one call" (List.length (api_calls r)) 1;
357
+ check "carries LATE01" (credential_is (auth_of r 0) "LATE01"));
358
+
359
+ test "error.a_builtin_that_cannot_read_is_an_error_not_a_miss" (fun () ->
360
+ (* dotenv pointed at a DIRECTORY: sekreto's own wording, from the
361
+ * vendored built-in, and nothing on the wire. *)
362
+ let (r, fetch) = recorder () in
363
+ let dir = Filename.get_temp_dir_name () in
364
+ let client = live fetch
365
+ [("providers", ja [jo [("kind", Str "dotenv"); ("file", Str dir)];
366
+ memory [("APIKEY", Str "MEM01")]])] in
367
+ let res = direct client in
368
+ check "refused" (not (res_ok res));
369
+ check ("sekreto's message: " ^ res_err res)
370
+ (contains (res_err res) "sekreto: dotenv provider cannot read");
371
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
372
+
373
+ (* ---------------------------------------------------------------------- *)
374
+ (* the init-failure gate: a chain that cannot be built refuses every *)
375
+ (* request; a malformed entry is refused, never dropped *)
376
+ (* ---------------------------------------------------------------------- *)
377
+
378
+ test "gate.a_bare_kind_name_is_refused_not_dropped" (fun () ->
379
+ let (r, fetch) = recorder () in
380
+ let client = live fetch
381
+ [("providers", ja [Str "hashicorp"; memory [("APIKEY", Str "MEM01")]])] in
382
+ let res = direct client in
383
+ check "refused" (not (res_ok res));
384
+ check ("sekreto's wording: " ^ res_err res)
385
+ (contains (res_err res) "sekreto: not a provider or a provider spec"
386
+ && contains (res_err res) "hashicorp");
387
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
388
+
389
+ test "gate.a_number_is_refused_not_dropped" (fun () ->
390
+ let (r, fetch) = recorder () in
391
+ let client = live fetch [("providers", ja [Num 42.; memory [("APIKEY", Str "MEM01")]])] in
392
+ let res = direct client in
393
+ check "refused" (not (res_ok res));
394
+ check "sekreto's wording" (contains (res_err res) "not a provider or a provider spec");
395
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
396
+
397
+ test "gate.a_null_hole_does_not_shorten_the_chain" (fun () ->
398
+ let (r, fetch) = recorder () in
399
+ let client = live fetch [("providers", ja [Null; memory [("APIKEY", Str "MEM01")]])] in
400
+ let res = direct client in
401
+ check "refused" (not (res_ok res));
402
+ check "sekreto's wording" (contains (res_err res) "not a provider or a provider spec");
403
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
404
+
405
+ test "gate.an_unknown_kind_is_refused_with_sekretos_message" (fun () ->
406
+ let (r, fetch) = recorder () in
407
+ let client = live fetch [("providers", ja [jo [("kind", Str "nosuchkind")]])] in
408
+ let res = direct client in
409
+ check "refused" (not (res_ok res));
410
+ check ("sekreto's message: " ^ res_err res)
411
+ (contains (res_err res) "sekreto: unknown provider kind: nosuchkind");
412
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
413
+
414
+ test "gate.an_invalid_secret_name_is_refused_not_skipped" (fun () ->
415
+ let (r, fetch) = recorder () in
416
+ let client = live ~sdkopts:[("apikey", Str "OPTKEY01")] fetch
417
+ [("providers", ja [working "CUSTOM01"]); ("name", Str "not a name!")] in
418
+ let res = direct client in
419
+ check "refused" (not (res_ok res));
420
+ check ("sekreto's message: " ^ res_err res) (contains (res_err res) "sekreto:");
421
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
422
+
423
+ test "gate.plugin_kinds_are_the_models_choice" (fun () ->
424
+ (* The vocabulary really is the model's: the definitions Config_ocaml
425
+ * selected, read back through the generated accessor. A plugin kind
426
+ * either resolves through its vendored module (here: refused by the
427
+ * store's own unreachable-address error, since nothing listens) or,
428
+ * when its group is off, is refused as "not passed in" - sekreto's
429
+ * own message in both cases, and nothing on the wire in either. *)
430
+ let defs = Sdk_config.feature_plugins "secrets" in
431
+ Printf.printf "secrets: %d plugin definition(s) selected by the model\n" (List.length defs);
432
+ let (r, fetch) = recorder () in
433
+ let client = live fetch
434
+ [("providers", ja [jo [("kind", Str "hashicorp"); ("addr", Str "http://127.0.0.1:1");
435
+ ("token", Str "t")]])] in
436
+ let res = direct client in
437
+ check "refused" (not (res_ok res));
438
+ let msg = res_err res in
439
+ Printf.printf "secrets: hashicorp kind -> %s\n" msg;
440
+ check ("sekreto's message: " ^ msg)
441
+ (contains msg "is a sekreto plugin, not built in" || contains msg "sekreto: cannot reach");
442
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0);
443
+
444
+ (* ---------------------------------------------------------------------- *)
445
+ (* auth suppression *)
446
+ (* ---------------------------------------------------------------------- *)
447
+
448
+ test "auth.null_suppresses_the_credential_chain_or_no_chain" (fun () ->
449
+ let (r, fetch) = recorder () in
450
+ let client = live ~sdkopts:[("auth", Null)] fetch
451
+ [("providers", ja [jo [("kind", Str "env"); ("prefix", Str envprefix)]])] in
452
+ check "ok" (res_ok (direct client));
453
+ check_int "one call" (List.length (api_calls r)) 1;
454
+ check "no header, though the chain resolved" (absent (auth_of r 0));
455
+ (* The suppression survives option validation as a present null. *)
456
+ check "options.auth survives as a present null"
457
+ (getprop_raw client.cl_options "auth" = Null));
458
+
459
+ test "auth.null_suppresses_an_explicit_apikey_too" (fun () ->
460
+ let (r, fetch) = recorder () in
461
+ let client = live ~sdkopts:[("auth", Null); ("apikey", Str "OPTKEY01")] fetch
462
+ [("providers", ja [working "CUSTOM01"])] in
463
+ check "ok" (res_ok (direct client));
464
+ check "no header" (absent (auth_of r 0)));
465
+
466
+ test "auth.null_suppresses_on_the_entity_path" (fun () ->
467
+ let (r, fetch) = recorder () in
468
+ let client = live ~sdkopts:[("auth", Null)] fetch [("providers", ja [working "CUSTOM01"])] in
469
+ (match drive_entity client r with
470
+ | Ok () -> ()
471
+ | Error msg -> failwith ("entity op failed: " ^ msg));
472
+ check_int "reached the transport once" (List.length (api_calls r)) 1;
473
+ check "no header" (absent (auth_of r 0)));
474
+
475
+ test "entity.carries_the_chain_resolved_credential" (fun () ->
476
+ let (r, fetch) = recorder () in
477
+ let client = live fetch [("providers", ja [jo [("kind", Str "env"); ("prefix", Str envprefix)]])] in
478
+ (match drive_entity client r with
479
+ | Ok () -> ()
480
+ | Error msg -> failwith ("entity op failed: " ^ msg));
481
+ check_int "reached the transport once" (List.length (api_calls r)) 1;
482
+ check "carries ENVKEY01" (credential_is (auth_of r 0) "ENVKEY01"));
483
+
484
+ (* ---------------------------------------------------------------------- *)
485
+ (* cache *)
486
+ (* ---------------------------------------------------------------------- *)
487
+
488
+ test "cache.caches_the_resolved_credential_by_default" (fun () ->
489
+ let (r, fetch) = recorder () in
490
+ let (fn, asked) = custom (fun _ -> Str "C01") in
491
+ let client = live fetch [("providers", ja [fn])] in
492
+ check "ok 1" (res_ok (direct client));
493
+ check "ok 2" (res_ok (direct client));
494
+ check_int "two calls" (List.length (api_calls r)) 2;
495
+ check_int "asked once" !asked 1;
496
+ check "both carry C01" (credential_is (auth_of r 0) "C01" && credential_is (auth_of r 1) "C01"));
497
+
498
+ test "cache.false_asks_the_chain_once_per_request" (fun () ->
499
+ let (r, fetch) = recorder () in
500
+ let (fn, asked) = custom (fun _ -> Str "C01") in
501
+ let client = live fetch [("providers", ja [fn]); ("cache", Bool false)] in
502
+ check "ok 1" (res_ok (direct client));
503
+ check "ok 2" (res_ok (direct client));
504
+ check_int "two calls" (List.length (api_calls r)) 2;
505
+ check_int "asked twice" !asked 2);
506
+
507
+ test "cache.an_uncached_miss_after_a_hit_retracts_the_credential" (fun () ->
508
+ let (r, fetch) = recorder () in
509
+ let (fn, _) = custom (fun n -> if n = 1 then Str "C01" else Null) in
510
+ let client = live fetch [("providers", ja [fn]); ("cache", Bool false)] in
511
+ check "ok 1" (res_ok (direct client));
512
+ check "first carries C01" (credential_is (auth_of r 0) "C01");
513
+ check "ok 2" (res_ok (direct client));
514
+ check "second carries nothing: the revoked value must not keep going out"
515
+ (absent (auth_of r 1)));
516
+
517
+ (* ---------------------------------------------------------------------- *)
518
+ (* the access-token exchange *)
519
+ (* ---------------------------------------------------------------------- *)
520
+
521
+ let xchg (extra : (string * value) list) : (string * value) =
522
+ ("exchange", jo (("active", Bool true) :: extra)) in
523
+ let refresh_chain (v : string) : (string * value) =
524
+ ("providers", ja [memory ~name:"refresh" [("REFRESH_TOKEN", Str v)]]) in
525
+
526
+ (* A token endpoint answering ACCESS<k> to the k-th purchase; the API
527
+ * answers `api` (status by the token it was handed). *)
528
+ let token_server (r : recorder) (api : string -> int) : unit =
529
+ r.reply <- Some (fun _n url fd ->
530
+ if is_token url then
531
+ ok200 (jo [("access_token", Str ("ACCESS" ^ string_of_int (List.length (token_calls r))))])
532
+ else
533
+ let token = match getp fd "headers" with
534
+ | Map _ as h -> (match Sdk_features.header_ci h "authorization" with Str s -> s | _ -> "")
535
+ | _ -> "" in
536
+ status_res (api token) (jo [("id", Str "r01")])) in
537
+
538
+ let body_of (call : value) : value =
539
+ match getp (getp call "fetchdef") "body" with
540
+ | Str s -> (try Sdk_json.json_read s with _ -> Noval)
541
+ | b -> b in
542
+
543
+ test "exchange.buys_an_access_token_with_the_resolved_refresh_token" (fun () ->
544
+ let (r, fetch) = recorder () in
545
+ token_server r (fun _ -> 200);
546
+ let client = live fetch [refresh_chain "R1"; ("name", Str "refresh_token"); xchg []] in
547
+ check "ok" (res_ok (direct client));
548
+ check_int "one purchase" (List.length (token_calls r)) 1;
549
+ check_int "one API call" (List.length (api_calls r)) 1;
550
+ check "the API call carries the bought token" (credential_is (auth_of r 0) "ACCESS1");
551
+ let tc = List.hd (token_calls r) in
552
+ check "POSTed to base + exchange.path"
553
+ ((match getp tc "url" with Str u -> u | _ -> "") = "http://secrets.test/api/auth/token");
554
+ check "the body is JSON-marshalled with the refresh token"
555
+ (getp (body_of tc) "refresh_token" = Str "R1"));
556
+
557
+ test "exchange.body_is_marshalled_not_concatenated" (fun () ->
558
+ let (r, fetch) = recorder () in
559
+ token_server r (fun _ -> 200);
560
+ let quoted = "R\"1\\x" in
561
+ let client = live fetch [refresh_chain quoted; ("name", Str "refresh_token"); xchg []] in
562
+ check "ok" (res_ok (direct client));
563
+ check "a refresh token carrying a quote and a backslash survives"
564
+ (getp (body_of (List.hd (token_calls r))) "refresh_token" = Str quoted));
565
+
566
+ test "exchange.a_spent_token_is_repurchased_and_retried_once" (fun () ->
567
+ let (r, fetch) = recorder () in
568
+ token_server r (fun token -> if credential_is (Str token) "ACCESS1" then 401 else 200);
569
+ let client = live fetch [refresh_chain "R1"; ("name", Str "refresh_token"); xchg []] in
570
+ check "ok" (res_ok (direct client));
571
+ check_int "two purchases" (List.length (token_calls r)) 2;
572
+ check_int "two API calls: the refusal and the retry" (List.length (api_calls r)) 2;
573
+ check "the retry carries the fresh token" (credential_is (auth_of r 1) "ACCESS2"));
574
+
575
+ test "exchange.a_second_refusal_surfaces_rather_than_spinning" (fun () ->
576
+ let (r, fetch) = recorder () in
577
+ token_server r (fun _ -> 401);
578
+ let client = live fetch [refresh_chain "R1"; ("name", Str "refresh_token"); xchg []] in
579
+ let res = direct client in
580
+ check "the refusal surfaces" (not (res_ok res));
581
+ check_vnum "with the API's status" (getp res "status") 401.;
582
+ check_int "exactly two API calls" (List.length (api_calls r)) 2;
583
+ check_int "exactly two purchases" (List.length (token_calls r)) 2);
584
+
585
+ test "exchange.retries_zero_never_repurchases" (fun () ->
586
+ let (r, fetch) = recorder () in
587
+ token_server r (fun _ -> 401);
588
+ let client = live fetch [refresh_chain "R1"; ("name", Str "refresh_token"); xchg [("retries", Num 0.)]] in
589
+ check "refused" (not (res_ok (direct client)));
590
+ check_int "one API call" (List.length (api_calls r)) 1;
591
+ check_int "one purchase" (List.length (token_calls r)) 1);
592
+
593
+ test "exchange.refresh_option_seats_first_as_the_explicit_credential" (fun () ->
594
+ let (r, fetch) = recorder () in
595
+ token_server r (fun _ -> 200);
596
+ let client = live fetch [refresh_chain "R2"; ("name", Str "refresh_token"); xchg [("refresh", Str "R1")]] in
597
+ check "ok" (res_ok (direct client));
598
+ check "the explicit refresh token was spent, not the chain's"
599
+ (getp (body_of (List.hd (token_calls r))) "refresh_token" = Str "R1"));
600
+
601
+ test "exchange.a_held_apikey_is_spent_before_anything_is_bought" (fun () ->
602
+ let (r, fetch) = recorder () in
603
+ token_server r (fun _ -> 200);
604
+ let client = live ~sdkopts:[("apikey", Str "HELD01")] fetch
605
+ [refresh_chain "R1"; ("name", Str "refresh_token"); xchg []] in
606
+ check "ok" (res_ok (direct client));
607
+ check_int "nothing bought" (List.length (token_calls r)) 0;
608
+ check "the held access token went out" (credential_is (auth_of r 0) "HELD01"));
609
+
610
+ test "exchange.no_refresh_token_anywhere_is_a_refusal_with_the_features_message" (fun () ->
611
+ let (r, fetch) = recorder () in
612
+ token_server r (fun _ -> 200);
613
+ let client = live fetch [("providers", ja []); ("name", Str "refresh_token"); xchg []] in
614
+ let res = direct client in
615
+ check "refused" (not (res_ok res));
616
+ check ("the feature's message: " ^ res_err res) (contains (res_err res) "secrets: no refresh token");
617
+ check_int "nothing reached the wire" (List.length (api_calls r)) 0;
618
+ check_int "nothing bought" (List.length (token_calls r)) 0);
619
+
620
+ test "exchange.without_a_transport_is_a_named_refusal" (fun () ->
621
+ (* This SDK's core bundles no HTTP client. With no options.system.fetch
622
+ * the purchase either has the vendored sekreto client (a plugin
623
+ * group needing one is active: it dials the loopback port nothing
624
+ * listens on and says so) or nothing at all (and says so). Never a
625
+ * silent unauthenticated send. *)
626
+ let client = Sdk_client.make (jo [
627
+ ("base", Str "http://127.0.0.1:1");
628
+ ("feature", jo [("secrets", jo [("active", Bool true); refresh_chain "R1";
629
+ ("name", Str "refresh_token"); xchg []])])]) in
630
+ let res = direct client in
631
+ check "refused" (not (res_ok res));
632
+ let msg = res_err res in
633
+ Printf.printf "secrets: exchange without system.fetch -> %s\n" msg;
634
+ check ("a named refusal: " ^ msg)
635
+ (contains msg "secrets: the token exchange has no HTTP transport"
636
+ || contains msg "sekreto: cannot reach"));
637
+
638
+ test "exchange.test_mode_buys_nothing" (fun () ->
639
+ (* A non-live client: the credential becomes the deterministic
640
+ * `test-<response>` and no purchase is attempted. Observed through
641
+ * ctrl.explain, which records the live fetchdef whose headers map
642
+ * the wrapper rewrites in place. *)
643
+ let client = Sdk_client.test_with Noval (jo [
644
+ ("feature", jo [("secrets", jo [("active", Bool true); refresh_chain "R1";
645
+ ("name", Str "refresh_token"); xchg []])])]) in
646
+ let explain = empty_map () in
647
+ let seen = ref false in
648
+ List.iter (fun name ->
649
+ if not !seen then
650
+ match Sdk_client.entity client name Noval with
651
+ | None -> ()
652
+ | Some ent ->
653
+ (try ignore (ent.e_list (empty_map ()) (jo [("explain", explain)])) with _ -> ());
654
+ (match getpath_s explain "fetchdef.headers" with
655
+ | Map _ -> seen := true
656
+ | _ -> (try ignore (ent.e_load (jo [("id", Str "id01")]) (jo [("explain", explain)])) with _ -> ());
657
+ (match getpath_s explain "fetchdef.headers" with Map _ -> seen := true | _ -> ())))
658
+ (entity_names ());
659
+ check "an entity op recorded its fetchdef" !seen;
660
+ let header = match getpath_s explain "fetchdef.headers" with
661
+ | Map _ as h -> Sdk_features.header_ci h "authorization"
662
+ | _ -> Noval in
663
+ check ("carries the deterministic test token: " ^ stringify header)
664
+ (credential_is header "test-access_token");
665
+ check_vnum "one (fake) purchase, tracked" (getp (track_get client "secrets") "buys") 1.);
666
+
667
+ ()
668
+
669
+ (* Printed from EXECUTIONS, for the generator's lane. *)
670
+ let () = Printf.printf "feature.secrets: ran %d check(s)\n" !ran