diff --git a/Cargo.lock b/Cargo.lock index 4ad6efbd3..8c3f2d2cc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,7 +29,7 @@ version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d122413f284cf2d62fb1b7db97e02edb8cda96d769b16e443a4f6195e35662b0" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "generic-array", ] @@ -41,7 +41,7 @@ checksum = "b169f7a6d4742236a0a00c541b845991d0ac43e546831af1249753ab4c3aa3a0" dependencies = [ "cfg-if", "cipher", - "cpufeatures", + "cpufeatures 0.2.17", ] [[package]] @@ -408,6 +408,49 @@ version = "1.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8" +[[package]] +name = "aws-config" +version = "1.8.18" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e33f815b73a3899c03b380d543532e5865f230dce9678d108dc10732a8682275" +dependencies = [ + "aws-credential-types", + "aws-runtime", + "aws-sdk-sso", + "aws-sdk-ssooidc", + "aws-sdk-sts", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "hex", + "http 1.4.0", + "sha1", + "time", + "tokio", + "tracing", + "url", + "zeroize", +] + +[[package]] +name = "aws-credential-types" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8f20799b373a1be121fe3005fba0c2090af9411573878f224df44b42727fcaf7" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "zeroize", +] + [[package]] name = "aws-lc-rs" version = "1.16.3" @@ -431,6 +474,339 @@ dependencies = [ "fs_extra", ] +[[package]] +name = "aws-runtime" +version = "1.7.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "77ed8e8c52d2dc2390ad9f15647fe663f71e9780b4262c190fbb823a32721566" +dependencies = [ + "aws-credential-types", + "aws-sigv4", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "bytes-utils", + "fastrand", + "http 1.4.0", + "http-body 1.0.1", + "percent-encoding", + "pin-project-lite", + "tracing", + "uuid", +] + +[[package]] +name = "aws-sdk-sso" +version = "1.101.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b647baea49ff551960b904f905681e9b4765a6c4ea08631e89dc52d8bd3f5896" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-ssooidc" +version = "1.103.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ae401c65ff288aa7873117fe535cd32b7b1bb0bc43751d28901a1d5f20636b9" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sdk-sts" +version = "1.106.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c80de7bb7d03e9ca8c9fd7b489f20f3948d3f3be91a7953591347d238115408" +dependencies = [ + "arc-swap", + "aws-credential-types", + "aws-runtime", + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-json", + "aws-smithy-observability", + "aws-smithy-query", + "aws-smithy-runtime", + "aws-smithy-runtime-api", + "aws-smithy-types", + "aws-smithy-xml", + "aws-types", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "regex-lite", + "tracing", +] + +[[package]] +name = "aws-sigv4" +version = "1.4.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bae38512beae0ffee7010fc24e7a8a123c53efdfef42a61e80fda4882418dc71" +dependencies = [ + "aws-credential-types", + "aws-smithy-http", + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "form_urlencoded", + "hex", + "hmac 0.13.0", + "http 0.2.12", + "http 1.4.0", + "percent-encoding", + "sha2 0.11.0", + "time", + "tracing", +] + +[[package]] +name = "aws-smithy-async" +version = "1.2.14" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2ffcaf626bdda484571968400c326a244598634dc75fd451325a54ad1a59acfc" +dependencies = [ + "futures-util", + "pin-project-lite", + "tokio", +] + +[[package]] +name = "aws-smithy-eventstream" +version = "0.60.21" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "78d8391e65fcea47c586a22e1a41f173b38615b112b2c6b7a44e80cec3e6b706" +dependencies = [ + "aws-smithy-types", + "bytes", + "crc32fast", +] + +[[package]] +name = "aws-smithy-http" +version = "0.63.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba1ab2dc1c2c3749ead27180d333c42f11be8b0e934058fb4b2258ee8dbe5231" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "bytes", + "bytes-utils", + "futures-core", + "futures-util", + "http 1.4.0", + "http-body 1.0.1", + "http-body-util", + "percent-encoding", + "pin-project-lite", + "pin-utils", + "tracing", +] + +[[package]] +name = "aws-smithy-http-client" +version = "1.1.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "5c3ef8931ad1c98aa6a55b4256f847f3116090819844e0dd41ea682cac5dd2d3" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-types", + "h2", + "http 1.4.0", + "hyper", + "hyper-rustls", + "hyper-util", + "pin-project-lite", + "rustls", + "rustls-native-certs", + "rustls-pki-types", + "tokio", + "tokio-rustls", + "tower", + "tracing", +] + +[[package]] +name = "aws-smithy-json" +version = "0.62.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "701a947f4797e52a911e114a898667c746c39feea467bbd1abd7b3721f702ffa" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", +] + +[[package]] +name = "aws-smithy-observability" +version = "0.2.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a06c2315d173edbf1920da8ba3a7189695827002e4c0fc961973ab1c54abca9c" +dependencies = [ + "aws-smithy-runtime-api", +] + +[[package]] +name = "aws-smithy-query" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1a56d79744fb3edb5d722ef79d86081e121d3b9422cb209eb03aea6aa4f21ebd" +dependencies = [ + "aws-smithy-types", + "urlencoding", +] + +[[package]] +name = "aws-smithy-runtime" +version = "1.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b8e6f5caf6fea86f8c2206541ab5857cfcda9013426cdbe8fa0098b9e2d32182" +dependencies = [ + "aws-smithy-async", + "aws-smithy-http", + "aws-smithy-http-client", + "aws-smithy-observability", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "bytes", + "fastrand", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "pin-project-lite", + "pin-utils", + "tokio", + "tracing", +] + +[[package]] +name = "aws-smithy-runtime-api" +version = "1.12.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9db177daa6ba8afb9ee1aefcf548c907abcf52065e394ee11a92780057fe0e8c" +dependencies = [ + "aws-smithy-async", + "aws-smithy-runtime-api-macros", + "aws-smithy-types", + "bytes", + "http 0.2.12", + "http 1.4.0", + "pin-project-lite", + "tokio", + "tracing", + "zeroize", +] + +[[package]] +name = "aws-smithy-runtime-api-macros" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8d7396fd9500589e62e460e987ecb671bad374934e55ec3b5f498cc7a8a8a7b7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + +[[package]] +name = "aws-smithy-schema" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7442cb268338f0eb8278140a107c046756aa01093d8ef5e99628d34ae09c94f5" +dependencies = [ + "aws-smithy-runtime-api", + "aws-smithy-types", + "http 1.4.0", +] + +[[package]] +name = "aws-smithy-types" +version = "1.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "32b42fcf341259d85ca10fac9a2f6448a8ec691c6955a18e45bc3b71a85fab85" +dependencies = [ + "base64-simd", + "bytes", + "bytes-utils", + "http 0.2.12", + "http 1.4.0", + "http-body 0.4.6", + "http-body 1.0.1", + "http-body-util", + "itoa", + "num-integer", + "pin-project-lite", + "pin-utils", + "ryu", + "serde", + "time", +] + +[[package]] +name = "aws-smithy-xml" +version = "0.60.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0ce02add1aa3677d022f8adf81dcbe3046a95f17a1b1e8979c145cd21d3d22b3" +dependencies = [ + "xmlparser", +] + +[[package]] +name = "aws-types" +version = "1.3.16" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d16bf10b03a3c01e6b3b7d47cd964e873ffe9e7d4e80fad16bd4c077cb068531" +dependencies = [ + "aws-credential-types", + "aws-smithy-async", + "aws-smithy-runtime-api", + "aws-smithy-schema", + "aws-smithy-types", + "rustc_version", + "tracing", +] + [[package]] name = "axum" version = "0.8.8" @@ -443,8 +819,8 @@ dependencies = [ "bytes", "form_urlencoded", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "hyper", "hyper-util", @@ -476,8 +852,8 @@ checksum = "08c78f31d7b1291f7ee735c1c6780ccde7785daae9a9206026862dab7d8792d1" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", @@ -499,8 +875,8 @@ dependencies = [ "cookie", "form_urlencoded", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "mime", "pin-project-lite", @@ -565,6 +941,16 @@ version = "0.22.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "72b3254f16251a8381aa12e40e3c4d2f0199f8c6508fbecb9d91f575e0fbb8c6" +[[package]] +name = "base64-simd" +version = "0.8.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" +dependencies = [ + "outref", + "vsimd", +] + [[package]] name = "bincode" version = "1.3.3" @@ -604,6 +990,15 @@ dependencies = [ "generic-array", ] +[[package]] +name = "block-buffer" +version = "0.12.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d2f6c7dbe95a6ed67ad9f18e57daf93a2f034c524b99fd2b76d18fdfeb6660aa" +dependencies = [ + "hybrid-array", +] + [[package]] name = "block2" version = "0.6.2" @@ -625,7 +1020,7 @@ dependencies = [ "futures-core", "futures-util", "hex", - "http", + "http 1.4.0", "http-body-util", "hyper", "hyper-named-pipe", @@ -710,6 +1105,16 @@ dependencies = [ "serde", ] +[[package]] +name = "bytes-utils" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7dafe3a8757b027e2be6e4e5601ed563c55989fcf1546e933c66c8eb3a058d35" +dependencies = [ + "bytes", + "either", +] + [[package]] name = "cc" version = "1.2.56" @@ -760,7 +1165,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "inout", ] @@ -832,6 +1237,12 @@ dependencies = [ "cc", ] +[[package]] +name = "cmov" +version = "0.5.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0c9ea0ac24bc397ab3c98583a3c9ba74fa56b09a4449bbe172b9b1ddb016027a" + [[package]] name = "cmsketch" version = "0.2.4" @@ -889,6 +1300,12 @@ dependencies = [ "windows-sys 0.61.2", ] +[[package]] +name = "const-oid" +version = "0.10.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a6ef517f0926dd24a1582492c791b6a4818a4d94e789a334894aa15b0d12f55c" + [[package]] name = "convert_case" version = "0.10.0" @@ -907,10 +1324,10 @@ dependencies = [ "aes-gcm", "base64", "hkdf", - "hmac", + "hmac 0.12.1", "percent-encoding", "rand 0.8.6", - "sha2", + "sha2 0.10.9", "subtle", "time", "version_check", @@ -987,6 +1404,15 @@ dependencies = [ "libc", ] +[[package]] +name = "cpufeatures" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b2a41393f66f16b0823bb79094d54ac5fbd34ab292ddafb9a0456ac9f87d201" +dependencies = [ + "libc", +] + [[package]] name = "crc32fast" version = "1.5.0" @@ -1137,6 +1563,15 @@ dependencies = [ "typenum", ] +[[package]] +name = "crypto-common" +version = "0.2.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce6e4c961d6cd6c9a86db418387425e8bdeaf05b3c8bc1411e6dca4c252f1453" +dependencies = [ + "hybrid-array", +] + [[package]] name = "csv" version = "1.4.0" @@ -1167,6 +1602,15 @@ dependencies = [ "cipher", ] +[[package]] +name = "ctutils" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +dependencies = [ + "cmov", +] + [[package]] name = "darling" version = "0.14.4" @@ -1467,11 +1911,23 @@ version = "0.10.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ - "block-buffer", - "crypto-common", + "block-buffer 0.10.4", + "crypto-common 0.1.7", "subtle", ] +[[package]] +name = "digest" +version = "0.11.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +dependencies = [ + "block-buffer 0.12.1", + "const-oid", + "crypto-common 0.2.2", + "ctutils", +] + [[package]] name = "dirs" version = "6.0.0" @@ -1707,7 +2163,7 @@ dependencies = [ "paste", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "shell-escape", "strum 0.28.0", "tempfile", @@ -1773,7 +2229,7 @@ dependencies = [ "croner", "hex", "serde", - "sha2", + "sha2 0.10.9", "tempfile", "thiserror 2.0.18", "tokio", @@ -1885,7 +2341,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "sha2", + "sha2 0.10.9", "shlex", "temp-env", "tempfile", @@ -2017,7 +2473,7 @@ dependencies = [ "fabro-types", "hex", "serde", - "sha2", + "sha2 0.10.9", "tempfile", "thiserror 2.0.18", "tokio", @@ -2090,7 +2546,7 @@ name = "fabro-http" version = "0.260.0-nightly.0" dependencies = [ "fabro-static", - "http", + "http 1.4.0", "reqwest 0.13.2", "thiserror 2.0.18", ] @@ -2132,6 +2588,12 @@ version = "0.260.0-nightly.0" dependencies = [ "anyhow", "async-trait", + "aws-config", + "aws-credential-types", + "aws-sigv4", + "aws-smithy-eventstream", + "aws-smithy-runtime-api", + "aws-smithy-types", "base64", "bytes", "fabro-auth", @@ -2144,7 +2606,7 @@ dependencies = [ "fabro-types", "fabro-util", "futures", - "http", + "http 1.4.0", "httpmock", "insta", "rand 0.9.4", @@ -2242,7 +2704,7 @@ name = "fabro-model" version = "0.260.0-nightly.0" dependencies = [ "fabro-static", - "http", + "http 1.4.0", "insta", "rust-embed", "serde", @@ -2270,7 +2732,7 @@ dependencies = [ "rand 0.9.4", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "tokio", "tracing", ] @@ -2333,14 +2795,14 @@ dependencies = [ "git2", "glob", "hex", - "hmac", + "hmac 0.12.1", "httpmock", "rand 0.9.4", "reqwest-middleware", "rustls", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "shlex", "strum 0.28.0", "tar", @@ -2406,7 +2868,7 @@ dependencies = [ "globset", "hex", "hkdf", - "hmac", + "hmac 0.12.1", "http-body-util", "httpmock", "jsonwebtoken", @@ -2421,7 +2883,7 @@ dependencies = [ "serde", "serde_json", "serde_yaml", - "sha2", + "sha2 0.10.9", "strum 0.28.0", "sysinfo", "tempfile", @@ -2615,7 +3077,7 @@ dependencies = [ "hex", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "strum 0.28.0", "tempfile", "toml 0.8.23", @@ -2736,7 +3198,7 @@ dependencies = [ "scopeguard", "serde", "serde_json", - "sha2", + "sha2 0.10.9", "shlex", "tempfile", "thiserror 2.0.18", @@ -3312,7 +3774,7 @@ dependencies = [ "fnv", "futures-core", "futures-sink", - "http", + "http 1.4.0", "indexmap 2.13.0", "slab", "tokio", @@ -3372,7 +3834,7 @@ dependencies = [ "base64", "bytes", "headers-core", - "http", + "http 1.4.0", "httpdate", "mime", "sha1", @@ -3384,7 +3846,7 @@ version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "54b4a22553d4242c49fddb9ba998a99962b5cc6f22cb5a3482bec22522403ce4" dependencies = [ - "http", + "http 1.4.0", ] [[package]] @@ -3411,7 +3873,7 @@ version = "0.12.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "7b5f8eb2ad728638ea2c7d47a21db23b7b58a72ed6a38256b8a1849f15fbbdf7" dependencies = [ - "hmac", + "hmac 0.12.1", ] [[package]] @@ -3420,7 +3882,16 @@ version = "0.12.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" dependencies = [ - "digest", + "digest 0.10.7", +] + +[[package]] +name = "hmac" +version = "0.13.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +dependencies = [ + "digest 0.11.3", ] [[package]] @@ -3456,6 +3927,17 @@ dependencies = [ "match_token", ] +[[package]] +name = "http" +version = "0.2.12" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" +dependencies = [ + "bytes", + "fnv", + "itoa", +] + [[package]] name = "http" version = "1.4.0" @@ -3466,6 +3948,17 @@ dependencies = [ "itoa", ] +[[package]] +name = "http-body" +version = "0.4.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7ceab25649e9960c0311ea418d17bee82c0dcec1bd053b5f9a66e265a693bed2" +dependencies = [ + "bytes", + "http 0.2.12", + "pin-project-lite", +] + [[package]] name = "http-body" version = "1.0.1" @@ -3473,7 +3966,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1efedce1fb8e6913f23e0c92de8e62cd5b772a67e7b3946df930a62566c93184" dependencies = [ "bytes", - "http", + "http 1.4.0", ] [[package]] @@ -3484,8 +3977,8 @@ checksum = "b021d93e26becf5dc7e1b75b1bed1fd93124b374ceb73f43d4d4eafec896a64a" dependencies = [ "bytes", "futures-core", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "pin-project-lite", ] @@ -3517,7 +4010,7 @@ dependencies = [ "futures-timer", "futures-util", "headers", - "http", + "http 1.4.0", "http-body-util", "hyper", "hyper-util", @@ -3541,6 +4034,15 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "135b12329e5e3ce057a9f972339ea52bc954fe1e9358ef27f95e89716fbc5424" +[[package]] +name = "hybrid-array" +version = "0.4.10" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3944cf8cf766b40e2a1a333ee5e9b563f854d5fa49d6a8ca2764e97c6eddb214" +dependencies = [ + "typenum", +] + [[package]] name = "hyper" version = "1.8.1" @@ -3552,8 +4054,8 @@ dependencies = [ "futures-channel", "futures-core", "h2", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "httparse", "httpdate", "itoa", @@ -3585,7 +4087,7 @@ version = "0.27.7" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3c93eb611681b207e1fe55d5a71ecf91572ec8a6705cdb6857f7d8d5242cf58" dependencies = [ - "http", + "http 1.4.0", "hyper", "hyper-util", "rustls", @@ -3607,8 +4109,8 @@ dependencies = [ "bytes", "futures-channel", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "hyper", "ipnet", "libc", @@ -4338,7 +4840,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d89e7ee0cfbedfc4da3340218492196241d89eefb6dab27de5df917a6d2e78cf" dependencies = [ "cfg-if", - "digest", + "digest 0.10.7", ] [[package]] @@ -4479,7 +4981,7 @@ dependencies = [ "bytes", "encoding_rs", "futures-util", - "http", + "http 1.4.0", "httparse", "memchr", "mime", @@ -4854,7 +5356,7 @@ dependencies = [ "chrono", "form_urlencoded", "futures", - "http", + "http 1.4.0", "http-body-util", "humantime", "hyper", @@ -5280,7 +5782,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9d1fe60d06143b2430aa532c94cfe9e29783047f06c0d7fd359a9a51b729fa25" dependencies = [ "cfg-if", - "cpufeatures", + "cpufeatures 0.2.17", "opaque-debug", "universal-hash", ] @@ -5452,7 +5954,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "de362a0477182f45accdbad4d43cd89a95a1db0a518a7c1ddf3e525e6896f0f0" dependencies = [ "heck 0.5.0", - "http", + "http 1.4.0", "indexmap 2.13.0", "openapiv3", "proc-macro2", @@ -5755,6 +6257,12 @@ dependencies = [ "regex-syntax", ] +[[package]] +name = "regex-lite" +version = "0.1.9" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cab834c73d247e67f4fae452806d17d3c7501756d98c8808d7c9c7aa7d18f973" + [[package]] name = "regex-syntax" version = "0.8.10" @@ -5783,8 +6291,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "hyper", "hyper-rustls", @@ -5830,8 +6338,8 @@ dependencies = [ "futures-core", "futures-util", "h2", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "http-body-util", "hyper", "hyper-rustls", @@ -5871,7 +6379,7 @@ checksum = "199dda04a536b532d0cc04d7979e39b1c763ea749bf91507017069c00b96056f" dependencies = [ "anyhow", "async-trait", - "http", + "http 1.4.0", "reqwest 0.13.2", "serde", "thiserror 2.0.18", @@ -5908,7 +6416,7 @@ dependencies = [ "base64", "chrono", "futures", - "http", + "http 1.4.0", "pastey", "pin-project-lite", "process-wrap", @@ -5970,7 +6478,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5bcdef0be6fe7f6fa333b1073c949729274b05f123a0ad7efcb8efd878e5c3b1" dependencies = [ "globset", - "sha2", + "sha2 0.10.9", "walkdir", ] @@ -6516,8 +7024,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e3bf829a2d51ab4a5ddf1352d8470c140cadc8301b2ae1789db023f01cedd6ba" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", ] [[package]] @@ -6527,8 +7035,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a7507d819769d01a365ab707794a4084392c824f54a7a6a7862f8c3d0892b283" dependencies = [ "cfg-if", - "cpufeatures", - "digest", + "cpufeatures 0.2.17", + "digest 0.10.7", +] + +[[package]] +name = "sha2" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +dependencies = [ + "cfg-if", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -6735,7 +7254,7 @@ checksum = "eb4dc4d33c68ec1f27d386b5610a351922656e1fdf5c05bbaad930cd1519479a" dependencies = [ "bytes", "futures-util", - "http-body", + "http-body 1.0.1", "http-body-util", "pin-project-lite", ] @@ -7355,8 +7874,8 @@ dependencies = [ "bitflags", "bytes", "futures-util", - "http", - "http-body", + "http 1.4.0", + "http-body 1.0.1", "iri-string", "pin-project-lite", "tower", @@ -7465,7 +7984,7 @@ checksum = "4793cb5e56680ecbb1d843515b23b6de9a75eb04b66643e256a396d43be33c13" dependencies = [ "bytes", "data-encoding", - "http", + "http 1.4.0", "httparse", "log", "rand 0.9.4", @@ -7484,7 +8003,7 @@ checksum = "8628dcc84e5a09eb3d8423d6cb682965dea9133204e8fb3efee74c2a0c259442" dependencies = [ "bytes", "data-encoding", - "http", + "http 1.4.0", "httparse", "log", "rand 0.9.4", @@ -7522,7 +8041,7 @@ dependencies = [ "fabro-http", "fabro-static", "futures-util", - "http", + "http 1.4.0", "serde", "serde_json", "tokio", @@ -7682,7 +8201,7 @@ version = "0.5.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ - "crypto-common", + "crypto-common 0.1.7", "subtle", ] @@ -7732,6 +8251,12 @@ dependencies = [ "serde_derive", ] +[[package]] +name = "urlencoding" +version = "2.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "daf8dba3b7eb870caf1ddeed7bc9d2a049f3cfdfae7cb521b087cc33ae4c49da" + [[package]] name = "utf-8" version = "0.7.6" @@ -8647,6 +9172,12 @@ dependencies = [ "markup5ever", ] +[[package]] +name = "xmlparser" +version = "0.13.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "66fee0b777b0f5ac1c69bb06d361268faafa61cd4682ae064a171c16c433e9e4" + [[package]] name = "yansi" version = "1.0.1" diff --git a/Cargo.toml b/Cargo.toml index 764649446..9528a14d9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -33,6 +33,22 @@ fs2 = "0.4" base64 = "0.22" bytes = "1" tokio-util = "0.7" +# AWS building blocks for the native Bedrock adapter. Lean stack: request +# signing + credential chain + event-stream decode only. Transport for the +# actual Bedrock inference calls stays on fabro-http; the full +# aws-sdk-bedrockruntime (and its parallel hyper stack) is not pulled in. +# aws-config keeps its DEFAULT features on purpose: `rt-tokio` supplies the +# TokioSleep impl the credential chain's retry requires (without it, +# resolving the default chain panics with "an async sleep implementation is +# required"), and `sso`/`credentials-process` make from_default_chain's +# documented SSO/credential-process support real. `rustls` pins the TLS +# backend for credential-resolution HTTP. +aws-config = { version = "1", features = ["behavior-version-latest", "rustls"] } +aws-credential-types = { version = "1", features = ["hardcoded-credentials"] } +aws-sigv4 = "1" +aws-smithy-eventstream = "0.60" +aws-smithy-runtime-api = "1" +aws-smithy-types = "1" clap = { version = "4", features = ["derive", "env"] } clap_complete = "4" jsonschema = { version = "0.42", default-features = false } diff --git a/lib/crates/fabro-auth/src/credential.rs b/lib/crates/fabro-auth/src/credential.rs index c8b59ed8c..d4ec91262 100644 --- a/lib/crates/fabro-auth/src/credential.rs +++ b/lib/crates/fabro-auth/src/credential.rs @@ -45,7 +45,13 @@ pub struct OAuthConfig { #[derive(Clone, PartialEq, Eq)] pub enum ApiKeyHeader { Bearer(String), - Custom { name: String, value: String }, + Custom { + name: String, + value: String, + }, + /// No static header: the request is authenticated by AWS SigV4 signing, + /// with credentials resolved from the AWS default chain at request time. + AwsSigv4, } fn redact_for_debug(value: &str) -> String { @@ -69,6 +75,7 @@ impl std::fmt::Debug for ApiKeyHeader { .field("name", name) .field("value", &redact_for_debug(value)) .finish(), + Self::AwsSigv4 => f.write_str("AwsSigv4"), } } } diff --git a/lib/crates/fabro-auth/src/resolve.rs b/lib/crates/fabro-auth/src/resolve.rs index 6daa97d28..96e259afd 100644 --- a/lib/crates/fabro-auth/src/resolve.rs +++ b/lib/crates/fabro-auth/src/resolve.rs @@ -28,6 +28,9 @@ pub(crate) enum ResolvedSecret { credential: Box, vault_name: String, }, + /// Opaque AWS SigV4 source: no static secret; the adapter signs requests + /// using the AWS default credential chain. + AwsSigv4, } #[derive(Debug, Clone, PartialEq, Eq)] @@ -333,6 +336,9 @@ impl CredentialResolver { Err(err) => Err(vault_lookup_error(provider, name, err)), }, CredentialRef::Env(name) => Ok((self.env_lookup)(name).map(ResolvedSecret::ApiKey)), + // AWS SigV4 is an opaque source: it always "resolves" (the adapter + // signs at request time from the AWS chain), no vault/env lookup. + CredentialRef::AwsSigv4 => Ok(Some(ResolvedSecret::AwsSigv4)), } } @@ -379,6 +385,21 @@ impl CredentialResolver { ) -> Result { let base_url = Self::provider_base_url_for_catalog(provider_id, catalog); match secret { + // Opaque AWS SigV4 source: carry the marker so the adapter signs + // with the AWS chain; no static secret resolved here. + ResolvedSecret::AwsSigv4 => Ok(ApiCredential { + provider: provider_id.clone(), + auth_header: Some(ApiKeyHeader::AwsSigv4), + extra_headers: self.resolved_extra_headers_for_catalog( + vault, + provider_id, + catalog, + )?, + base_url, + codex_mode: false, + org_id: None, + project_id: None, + }), ResolvedSecret::ApiKey(key) => { let provider = catalog .provider(provider_id) @@ -579,6 +600,37 @@ mod tests { ); } + #[tokio::test] + async fn sigv4_provider_resolves_to_aws_sigv4_credential() { + let dir = tempfile::tempdir().unwrap(); + let vault = Vault::load(dir.path().join("secrets.json")).unwrap(); + // No env credentials configured: SigV4 must still resolve. + let resolver = test_resolver(vault, Arc::new(|_| None)); + let catalog = catalog_with( + r#" +[providers.bedrock] +adapter = "bedrock" +base_url = "https://bedrock-runtime.eu-west-1.amazonaws.com" + +[providers.bedrock.auth] +credentials = ["aws_sigv4"] +"#, + ); + + let resolved = resolver + .resolve( + ProviderId::from("bedrock"), + CredentialUsage::ApiRequest, + &catalog, + ) + .await + .unwrap(); + + let ResolvedCredential::Api(api) = resolved; + assert_eq!(api.provider, ProviderId::from("bedrock")); + assert_eq!(api.auth_header, Some(ApiKeyHeader::AwsSigv4)); + } + #[tokio::test] async fn resolve_returns_not_configured_for_missing_provider() { let dir = tempfile::tempdir().unwrap(); diff --git a/lib/crates/fabro-auth/src/strategies/api_key.rs b/lib/crates/fabro-auth/src/strategies/api_key.rs index 6a815d1c6..0d594110a 100644 --- a/lib/crates/fabro-auth/src/strategies/api_key.rs +++ b/lib/crates/fabro-auth/src/strategies/api_key.rs @@ -23,7 +23,7 @@ impl ApiKeyStrategy { .iter() .filter_map(|credential_ref| match credential_ref { CredentialRef::Env(name) => Some(name.clone()), - CredentialRef::Vault(_) => None, + CredentialRef::Vault(_) | CredentialRef::AwsSigv4 => None, }) .collect() }) diff --git a/lib/crates/fabro-cli/src/commands/install.rs b/lib/crates/fabro-cli/src/commands/install.rs index 281ba1ec7..4c40e3dad 100644 --- a/lib/crates/fabro-cli/src/commands/install.rs +++ b/lib/crates/fabro-cli/src/commands/install.rs @@ -102,7 +102,7 @@ fn provider_env_var_label(provider: &ProviderId, catalog: &Catalog) -> String { .iter() .filter_map(|credential| match credential { CredentialRef::Env(name) => Some(name.as_str()), - CredentialRef::Vault(_) => None, + CredentialRef::Vault(_) | CredentialRef::AwsSigv4 => None, }) .collect::>() .join(" / ") diff --git a/lib/crates/fabro-llm/Cargo.toml b/lib/crates/fabro-llm/Cargo.toml index 482447b17..9146976b6 100644 --- a/lib/crates/fabro-llm/Cargo.toml +++ b/lib/crates/fabro-llm/Cargo.toml @@ -32,6 +32,12 @@ base64.workspace = true bytes.workspace = true tokio-util.workspace = true tracing.workspace = true +aws-config.workspace = true +aws-credential-types.workspace = true +aws-sigv4.workspace = true +aws-smithy-eventstream.workspace = true +aws-smithy-runtime-api.workspace = true +aws-smithy-types.workspace = true fabro-http.workspace = true fabro-auth = { path = "../fabro-auth" } fabro-model = { path = "../fabro-model" } diff --git a/lib/crates/fabro-llm/src/adapter_registry.rs b/lib/crates/fabro-llm/src/adapter_registry.rs index bf88770d3..a14c3083c 100644 --- a/lib/crates/fabro-llm/src/adapter_registry.rs +++ b/lib/crates/fabro-llm/src/adapter_registry.rs @@ -90,7 +90,9 @@ fn apply_primary_auth_header( extra_headers.insert(name, value); None } - None => None, + // SigV4 is not a static header; only the Bedrock adapter consumes + // the marker (it signs at request time). + Some(ApiKeyHeader::AwsSigv4) | None => None, } } @@ -205,6 +207,23 @@ fn build_openai_compatible(config: AdapterConfig) -> Result Result, Error> { + Err(Error::Configuration { + message: format!( + "provider '{}': the bedrock adapter is not yet wired", + config.provider_id + ), + source: None, + }) +} + /// Return the factory for a known adapter kind. #[must_use] pub fn factory_for(adapter_kind: AdapterKind) -> AdapterFactory { @@ -213,6 +232,7 @@ pub fn factory_for(adapter_kind: AdapterKind) -> AdapterFactory { AdapterKind::OpenAi => build_openai, AdapterKind::Gemini => build_gemini, AdapterKind::OpenAiCompatible => build_openai_compatible, + AdapterKind::Bedrock => build_bedrock, } } diff --git a/lib/crates/fabro-model/src/adapter.rs b/lib/crates/fabro-model/src/adapter.rs index baa74eb7e..db67fe132 100644 --- a/lib/crates/fabro-model/src/adapter.rs +++ b/lib/crates/fabro-model/src/adapter.rs @@ -32,6 +32,7 @@ pub enum AdapterKind { #[serde(rename = "openai_compatible")] #[strum(to_string = "openai_compatible")] OpenAiCompatible, + Bedrock, } impl AdapterKind { @@ -87,6 +88,16 @@ mod tests { } } + #[test] + fn bedrock_adapter_kind_roundtrips() { + assert_eq!(AdapterKind::Bedrock.as_str(), "bedrock"); + assert_eq!( + "bedrock".parse::().unwrap(), + AdapterKind::Bedrock + ); + assert!(AdapterKind::VARIANTS.contains(&AdapterKind::Bedrock)); + } + #[test] fn agent_profile_kind_round_trips_as_settings_strings() { for (kind, expected) in [ diff --git a/lib/crates/fabro-model/src/catalog.rs b/lib/crates/fabro-model/src/catalog.rs index 480759d58..a8168b88f 100644 --- a/lib/crates/fabro-model/src/catalog.rs +++ b/lib/crates/fabro-model/src/catalog.rs @@ -171,11 +171,20 @@ pub struct CostRates { pub cache_input_cost_per_mtok: Option, } +/// Where a provider's credential comes from. +/// +/// `Vault`/`Env` reference a stored secret resolved to an auth header. +/// `AwsSigv4` is an opaque source: the credential comes from the AWS default +/// credential chain and the request is SigV4-signed rather than carrying a +/// static secret. Folding this into the credential list (instead of a separate +/// `scheme` field) keeps the "where do credentials come from" decision in one +/// place and makes invalid combinations unrepresentable. #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(into = "String", try_from = "String")] pub enum CredentialRef { Vault(String), Env(String), + AwsSigv4, } impl std::fmt::Display for CredentialRef { @@ -183,6 +192,7 @@ impl std::fmt::Display for CredentialRef { match self { Self::Vault(name) => write!(f, "vault:{name}"), Self::Env(name) => write!(f, "env:{name}"), + Self::AwsSigv4 => write!(f, "aws_sigv4"), } } } @@ -209,6 +219,9 @@ impl FromStr for CredentialRef { } return Ok(Self::Env(name.to_string())); } + if value == "aws_sigv4" { + return Ok(Self::AwsSigv4); + } Err(CredentialRefParseError::Invalid) } } @@ -223,7 +236,7 @@ impl TryFrom for CredentialRef { #[derive(Debug, Clone, Copy, PartialEq, Eq, thiserror::Error)] pub enum CredentialRefParseError { - #[error("credential reference must be `vault:` or `env:`")] + #[error("credential reference must be `vault:`, `env:`, or `aws_sigv4`")] Invalid, #[error("credential reference is missing a name after `vault:`")] EmptyVault, @@ -234,6 +247,9 @@ pub enum CredentialRefParseError { #[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)] #[serde(deny_unknown_fields)] pub struct ProviderAuthConfig { + /// Ordered credential sources; the first that resolves wins. Static secrets + /// use `env:` / `vault:`; AWS SigV4 (Bedrock) uses `aws_sigv4`, + /// which resolves opaquely from the AWS credential chain. pub credentials: Vec, #[serde(default)] pub header: ApiKeyHeaderPolicy, @@ -511,7 +527,7 @@ impl CatalogProvider { .iter() .find_map(|credential_ref| match credential_ref { CredentialRef::Vault(name) => Some(name.as_str()), - CredentialRef::Env(_) => None, + CredentialRef::Env(_) | CredentialRef::AwsSigv4 => None, }) } } @@ -1367,7 +1383,9 @@ struct AdapterDefaults { fn adapter_defaults(adapter: AdapterKind) -> AdapterDefaults { match adapter { - AdapterKind::Anthropic => AdapterDefaults { + // Bedrock hosts Anthropic-family models, so it shares the Anthropic + // agent profile and billing policy by default. + AdapterKind::Anthropic | AdapterKind::Bedrock => AdapterDefaults { agent_profile: AgentProfileKind::Anthropic, billing_policy: BillingPolicy::Anthropic, }, @@ -1832,6 +1850,56 @@ mod tests { toml::from_str(source).expect("fixture should parse as an LLM settings layer") } + const BEDROCK_SIGV4_LAYER: &str = r#" +[providers.bedrock] +adapter = "bedrock" +base_url = "https://bedrock-runtime.eu-west-1.amazonaws.com" + +[providers.bedrock.auth] +credentials = ["aws_sigv4"] + +[models."bedrock-sonnet"] +provider = "bedrock" +api_id = "anthropic.claude-sonnet-4-6" +display_name = "Bedrock Sonnet" +family = "claude-4" +default = true + +[models."bedrock-sonnet".limits] +context_window = 200000 +max_output = 64000 + +[models."bedrock-sonnet".features] +tools = true +vision = true +reasoning = true +"#; + + #[test] + fn provider_parses_bedrock_base_url_and_sigv4_credential() { + let catalog = Catalog::from_settings(&minimal_settings(BEDROCK_SIGV4_LAYER)).unwrap(); + let provider = catalog.provider(&ProviderId::from("bedrock")).unwrap(); + assert_eq!( + provider.base_url.as_deref(), + Some("https://bedrock-runtime.eu-west-1.amazonaws.com") + ); + assert_eq!(provider.auth.as_ref().unwrap().credentials, vec![ + CredentialRef::AwsSigv4 + ]); + // Bedrock inherits the Anthropic agent profile and billing by default. + assert_eq!(provider.agent_profile, AgentProfileKind::Anthropic); + assert_eq!(provider.billing_policy, BillingPolicy::Anthropic); + } + + #[test] + fn aws_sigv4_credential_round_trips() { + assert_eq!( + "aws_sigv4".parse::().unwrap(), + CredentialRef::AwsSigv4 + ); + assert_eq!(CredentialRef::AwsSigv4.to_string(), "aws_sigv4"); + } + // ---- Catalog struct tests ---- #[test] diff --git a/lib/crates/fabro-model/src/codec.rs b/lib/crates/fabro-model/src/codec.rs index bc8bf8813..b9667d286 100644 --- a/lib/crates/fabro-model/src/codec.rs +++ b/lib/crates/fabro-model/src/codec.rs @@ -40,6 +40,10 @@ pub enum CodecKind { #[strum(to_string = "openai_compatible")] OpenAiCompatible, GeminiGenerate, + /// Amazon Bedrock's unified Converse/ConverseStream dialect: one + /// model-agnostic envelope AWS translates to each hosted family's + /// native format server-side. + BedrockConverse, } impl CodecKind { @@ -53,6 +57,7 @@ impl CodecKind { AdapterKind::OpenAi => Self::OpenAiResponses, AdapterKind::Gemini => Self::GeminiGenerate, AdapterKind::OpenAiCompatible => Self::OpenAiCompatible, + AdapterKind::Bedrock => Self::BedrockConverse, } } @@ -90,6 +95,7 @@ mod tests { (CodecKind::OpenAiResponses, "openai_responses"), (CodecKind::OpenAiCompatible, "openai_compatible"), (CodecKind::GeminiGenerate, "gemini_generate"), + (CodecKind::BedrockConverse, "bedrock_converse"), ] { assert_eq!(kind.as_str(), expected); assert_eq!(kind.to_string(), expected); @@ -103,6 +109,7 @@ mod tests { (AdapterKind::OpenAi, CodecKind::OpenAiResponses), (AdapterKind::Gemini, CodecKind::GeminiGenerate), (AdapterKind::OpenAiCompatible, CodecKind::OpenAiCompatible), + (AdapterKind::Bedrock, CodecKind::BedrockConverse), ] { assert_eq!(CodecKind::default_for(adapter), expected); }