├── bin ├── .keep ├── setup ├── clippy ├── test-local ├── console ├── build ├── test └── build-arch ├── test ├── libcrypteia │ ├── empty-node.sh │ ├── empty-ruby.sh │ ├── empty-php.sh │ ├── empty-python.sh │ ├── existing-ruby.sh │ ├── existing-node.sh │ ├── existing-php.sh │ ├── _envfile.sh │ ├── override-ruby.sh │ ├── existing-python.sh │ ├── override-node.sh │ ├── override-php.sh │ ├── fullpath-php.sh │ ├── fullpath-ruby.sh │ ├── fullpath-node.sh │ ├── override-python.sh │ └── fullpath-python.sh ├── libcrypteia.sh └── assert.sh ├── images ├── readme-code-results.png ├── readme-env-variables.png ├── readme-devcontainer-vscode.png ├── readme-devcontainer-cli-build.png ├── readme-devcontainer-cli-sublime.png └── readme-devcontainer-open-folder.png ├── python ├── crypteia │ ├── setup.py │ ├── setup.cfg │ └── src │ │ └── crypteia │ │ └── __init__.py └── usercustomize.py ├── .gitignore ├── package ├── Dockerfile ├── deploy ├── template.yml ├── deploy-image-amzn └── deploy-image-debian ├── debian ├── test-arm64 ├── setup-arm64 └── Dockerfile-arm64 ├── py27 ├── test ├── setup ├── Dockerfile └── Dockerfile-test ├── .devcontainer ├── postCreate ├── devcontainer.json └── Dockerfile ├── amzn ├── setup ├── Dockerfile-test ├── Dockerfile ├── Dockerfile-test-arm64 ├── Dockerfile-arm64 ├── setup-arm64 ├── test └── test-arm64 ├── amzn2023 ├── setup ├── Dockerfile-test ├── Dockerfile-test-arm64 ├── setup-arm64 ├── Dockerfile ├── Dockerfile-arm64 ├── test └── test-arm64 ├── Cargo.toml ├── src ├── log.rs ├── main.rs ├── lib.rs └── ssm.rs ├── LICENSE ├── CHANGELOG.md ├── .github └── workflows │ ├── release.yml │ └── test.yml ├── CODE_OF_CONDUCT.md ├── README.md └── Cargo.lock /bin/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | ./bin/build 5 | -------------------------------------------------------------------------------- /bin/clippy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | cargo clippy --fix 5 | -------------------------------------------------------------------------------- /bin/test-local: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | SKIP_CARGO_TEST=1 ./bin/test 5 | -------------------------------------------------------------------------------- /test/libcrypteia/empty-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | node --print "process.env.EMPTY" 5 | -------------------------------------------------------------------------------- /test/libcrypteia/empty-ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | ruby -e "puts('undefined') if ENV['EMPTY'].nil?" 5 | -------------------------------------------------------------------------------- /images/readme-code-results.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-lambda/crypteia/HEAD/images/readme-code-results.png -------------------------------------------------------------------------------- /images/readme-env-variables.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-lambda/crypteia/HEAD/images/readme-env-variables.png -------------------------------------------------------------------------------- /test/libcrypteia/empty-php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | php -r "print(getenv('EMPTY') ? 'FOUND' : 'undefined');" 5 | -------------------------------------------------------------------------------- /images/readme-devcontainer-vscode.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-lambda/crypteia/HEAD/images/readme-devcontainer-vscode.png -------------------------------------------------------------------------------- /test/libcrypteia/empty-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | python -c "import os; print(os.environ.get('EMPTY','undefined'))" 5 | -------------------------------------------------------------------------------- /images/readme-devcontainer-cli-build.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-lambda/crypteia/HEAD/images/readme-devcontainer-cli-build.png -------------------------------------------------------------------------------- /test/libcrypteia/existing-ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export EXISTING=existingvalue 5 | 6 | ruby -e "puts ENV['EXISTING']" 7 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export HELLO=YALL 5 | export LD_PRELOAD=$PWD/libcrypteia/build/libcrypteia-debian.so 6 | 7 | irb 8 | -------------------------------------------------------------------------------- /images/readme-devcontainer-cli-sublime.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-lambda/crypteia/HEAD/images/readme-devcontainer-cli-sublime.png -------------------------------------------------------------------------------- /images/readme-devcontainer-open-folder.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rails-lambda/crypteia/HEAD/images/readme-devcontainer-open-folder.png -------------------------------------------------------------------------------- /test/libcrypteia/existing-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export EXISTING=existingvalue 5 | 6 | node --print "process.env.EXISTING" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/existing-php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export EXISTING=existingvalue 5 | 6 | php -r "print(getenv('EXISTING'));" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/_envfile.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ -e $CRYPTEIA_ENV_FILE ]; then 5 | echo "PRESENT" 6 | else 7 | echo "REMOVED" 8 | fi 9 | -------------------------------------------------------------------------------- /test/libcrypteia/override-ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SECRET=x-crypteia-ssm:/crypteia/v5/myapp/SECRET 5 | 6 | ruby -e "puts ENV['SECRET']" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/existing-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export EXISTING=existingvalue 5 | 6 | python -c "import os; print(os.environ.get('EXISTING',''))" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/override-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SECRET=x-crypteia-ssm:/crypteia/v5/myapp/SECRET 5 | 6 | node --print "process.env.SECRET" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/override-php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SECRET=x-crypteia-ssm:/crypteia/v5/myapp/SECRET 5 | 6 | php -r "print(getenv('SECRET'));" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/fullpath-php.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export X_CRYPTEIA_SSM=x-crypteia-ssm-path:/crypteia/v5/myapp/envs 5 | 6 | php -r "print(getenv('X_CRYPTEIA_SSM'));" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/fullpath-ruby.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export X_CRYPTEIA_SSM=x-crypteia-ssm-path:/crypteia/v5/myapp/envs 5 | 6 | ruby -e "puts ENV['X_CRYPTEIA_SSM']" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/fullpath-node.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export X_CRYPTEIA_SSM=x-crypteia-ssm-path:/crypteia/v5/myapp/envs 5 | 6 | node --print "process.env.X_CRYPTEIA_SSM" 7 | -------------------------------------------------------------------------------- /test/libcrypteia/override-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export SECRET=x-crypteia-ssm:/crypteia/v5/myapp/SECRET 5 | 6 | python -c "import os; print(os.environ.get('SECRET',''))" 7 | -------------------------------------------------------------------------------- /python/crypteia/setup.py: -------------------------------------------------------------------------------- 1 | from setuptools import setup 2 | 3 | setup( 4 | version="0.1.0", 5 | install_requires=["wrapt>=1.10.4,<1.15.0"] # Pin to version compatible with Python 2.7 6 | ) 7 | -------------------------------------------------------------------------------- /test/libcrypteia/fullpath-python.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | export X_CRYPTEIA_SSM=x-crypteia-ssm-path:/crypteia/v5/myapp/envs 5 | 6 | python -c "import os; print(os.environ.get('X_CRYPTEIA_SSM',''))" 7 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /build 2 | /target 3 | /package/opt 4 | /package/package.zip 5 | /package/packaged.yaml 6 | outputs.json 7 | python/crypteia/build 8 | python/crypteia/src/*.egg-info 9 | runteststest 10 | .DS_Store 11 | -------------------------------------------------------------------------------- /package/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | LABEL org.opencontainers.image.source "https://github.com/rails-lambda/crypteia" 3 | LABEL org.opencontainers.image.description "Rust Lambda Extension for any Runtime to preload SSM Parameters as Secure Environment Variables!" 4 | COPY ./package/opt /opt 5 | -------------------------------------------------------------------------------- /debian/test-arm64: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [debian/Dockerfile-arm64] bin/test ==" 5 | docker run \ 6 | --rm \ 7 | --user root \ 8 | --entrypoint "./test/libcrypteia.sh" \ 9 | --volume "${PWD}:/var/task" \ 10 | --env TEST_LANG=node \ 11 | --platform=linux/arm64 \ 12 | crypteia-debian-nodejs-arm64 13 | -------------------------------------------------------------------------------- /py27/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [py27/Dockerfile-test] bin/test ==" 5 | docker run \ 6 | --rm \ 7 | --user root \ 8 | --env TEST_LANG=python \ 9 | --entrypoint "./test/libcrypteia.sh" \ 10 | --volume "${PWD}:/var/task" \ 11 | --workdir "/var/task" \ 12 | crypteia-debian-py27-test \ 13 | sh 14 | -------------------------------------------------------------------------------- /.devcontainer/postCreate: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Wait for docker to be ready 5 | TIMEOUT=30 6 | while ! docker info > /dev/null 2>&1; do 7 | echo "Waiting for docker daemon..." 8 | sleep 1 9 | TIMEOUT=$((TIMEOUT - 1)) 10 | if [ $TIMEOUT -le 0 ]; then 11 | echo "Docker daemon failed to start" 12 | exit 1 13 | fi 14 | done 15 | -------------------------------------------------------------------------------- /amzn/setup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn/Dockerfile] sam/build building... ==" 5 | docker build --tag crypteia-lambda-nodejs --file amzn/Dockerfile . 6 | 7 | echo "== [amzn/Dockerfile] sam/build bin/setup ==" 8 | docker run \ 9 | --rm \ 10 | --user root \ 11 | --entrypoint "./bin/setup" \ 12 | --volume "${PWD}:/var/task" \ 13 | crypteia-lambda-nodejs 14 | -------------------------------------------------------------------------------- /amzn2023/setup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn2023/Dockerfile] building... ==" 5 | docker build --tag crypteia-lambda-amzn2023 --file amzn2023/Dockerfile . 6 | 7 | echo "== [amzn2023/Dockerfile] bin/setup ==" 8 | docker run \ 9 | --rm \ 10 | --user root \ 11 | --entrypoint "./bin/setup" \ 12 | --volume "${PWD}:/var/task" \ 13 | crypteia-lambda-amzn2023 14 | 15 | -------------------------------------------------------------------------------- /amzn/Dockerfile-test: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:18 2 | 3 | COPY build/crypteia-amzn /opt/extensions/crypteia 4 | COPY build/libcrypteia-amzn.so /opt/lib/libcrypteia.so 5 | 6 | ENV CRYPTEIA_BUILD_OS=amzn 7 | ENV SKIP_CARGO_TEST=1 8 | 9 | ENV EXISTING=existingvalue 10 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 11 | 12 | # For assert.sh support 13 | RUN yum install -y util-linux 14 | -------------------------------------------------------------------------------- /amzn/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/sam/build-nodejs18.x 2 | 3 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 4 | ENV PATH="~/.cargo/bin:${PATH}" 5 | 6 | RUN ~/.cargo/bin/rustup update \ 7 | && ~/.cargo/bin/rustup target add aarch64-unknown-linux-gnu 8 | 9 | RUN rustup default stable 10 | ENV CRYPTEIA_BUILD_OS=amzn 11 | ENV CRYPTEIA_BUILD_TARGET=x86_64-unknown-linux-gnu 12 | -------------------------------------------------------------------------------- /amzn/Dockerfile-test-arm64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:18-arm64 2 | 3 | COPY build/crypteia-amzn-arm64 /opt/extensions/crypteia 4 | COPY build/libcrypteia-amzn-arm64.so /opt/lib/libcrypteia.so 5 | 6 | ENV CRYPTEIA_BUILD_OS=amzn 7 | ENV SKIP_CARGO_TEST=1 8 | 9 | ENV EXISTING=existingvalue 10 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 11 | 12 | # For assert.sh support 13 | RUN yum install -y util-linux 14 | -------------------------------------------------------------------------------- /amzn/Dockerfile-arm64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/sam/build-nodejs18.x:latest-arm64 2 | 3 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 4 | ENV PATH="~/.cargo/bin:${PATH}" 5 | 6 | RUN ~/.cargo/bin/rustup update \ 7 | && ~/.cargo/bin/rustup target add aarch64-unknown-linux-gnu 8 | 9 | RUN rustup default stable 10 | ENV CRYPTEIA_BUILD_OS=amzn 11 | ENV CRYPTEIA_BUILD_TARGET=aarch64-unknown-linux-gnu 12 | -------------------------------------------------------------------------------- /amzn2023/Dockerfile-test: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:22 2 | 3 | COPY build/crypteia-amzn /opt/extensions/crypteia 4 | COPY build/libcrypteia-amzn.so /opt/lib/libcrypteia.so 5 | 6 | WORKDIR /var/task 7 | 8 | ENV CRYPTEIA_BUILD_OS=amzn 9 | ENV SKIP_CARGO_TEST=1 10 | 11 | ENV EXISTING=existingvalue 12 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 13 | 14 | # For assert.sh support 15 | RUN dnf install -y util-linux && dnf clean all 16 | -------------------------------------------------------------------------------- /amzn/setup-arm64: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn/Dockerfile-arm64] sam/build building... ==" 5 | docker build --tag crypteia-lambda-nodejs-arm64 --file amzn/Dockerfile-arm64 . 6 | 7 | echo "== [amzn/Dockerfile-arm64] sam/build bin/setup ==" 8 | docker run \ 9 | --rm \ 10 | --user root \ 11 | --entrypoint "./bin/setup" \ 12 | --volume "${PWD}:/var/task" \ 13 | --platform=linux/arm64 \ 14 | crypteia-lambda-nodejs-arm64 15 | -------------------------------------------------------------------------------- /debian/setup-arm64: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [debian/Dockerfile-arm64] building... ==" 5 | docker build --platform=linux/arm64 --tag crypteia-debian-nodejs-arm64 --file debian/Dockerfile-arm64 . 6 | 7 | echo "== [debian/Dockerfile-arm64] bin/setup ==" 8 | docker run \ 9 | --rm \ 10 | --user root \ 11 | --entrypoint "./bin/setup" \ 12 | --volume "${PWD}:/var/task" \ 13 | --platform=linux/arm64 \ 14 | crypteia-debian-nodejs-arm64 15 | -------------------------------------------------------------------------------- /amzn2023/Dockerfile-test-arm64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/lambda/nodejs:22-arm64 2 | 3 | COPY build/crypteia-amzn-arm64 /opt/extensions/crypteia 4 | COPY build/libcrypteia-amzn-arm64.so /opt/lib/libcrypteia.so 5 | 6 | WORKDIR /var/task 7 | 8 | ENV CRYPTEIA_BUILD_OS=amzn 9 | ENV SKIP_CARGO_TEST=1 10 | 11 | ENV EXISTING=existingvalue 12 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 13 | 14 | # For assert.sh support 15 | RUN dnf install -y util-linux && dnf clean all 16 | 17 | -------------------------------------------------------------------------------- /amzn2023/setup-arm64: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn2023/Dockerfile-arm64] building... ==" 5 | docker build --platform linux/arm64 --tag crypteia-lambda-amzn2023-arm64 --file amzn2023/Dockerfile-arm64 . 6 | 7 | echo "== [amzn2023/Dockerfile-arm64] bin/setup ==" 8 | docker run \ 9 | --platform linux/arm64 \ 10 | --rm \ 11 | --user root \ 12 | --entrypoint "./bin/setup" \ 13 | --volume "${PWD}:/var/task" \ 14 | crypteia-lambda-amzn2023-arm64 15 | -------------------------------------------------------------------------------- /py27/setup: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [py27/Dockerfile] building... ==" 5 | docker build --tag crypteia-debian-py27 --file py27/Dockerfile . 6 | 7 | echo "== [py27/Dockerfile] bin/setup ==" 8 | docker run \ 9 | --rm \ 10 | --user root \ 11 | --entrypoint "./bin/setup" \ 12 | --volume "${PWD}:/var/task" \ 13 | crypteia-debian-py27 14 | 15 | echo "== [py27/Dockerfile-test] building... ==" 16 | docker build --tag crypteia-debian-py27-test --file py27/Dockerfile-test . 17 | -------------------------------------------------------------------------------- /python/crypteia/setup.cfg: -------------------------------------------------------------------------------- 1 | [metadata] 2 | name = crypteia 3 | author = Ken Collins (ken@metaskills.net) 4 | description = Crypteia 5 | license = MIT 6 | url = https://github.com/rails-lambda/crypteia 7 | classifiers = 8 | Programming Language :: Python :: 2 9 | Programming Language :: Python :: 2.7 10 | Programming Language :: Python :: 3 11 | 12 | [options] 13 | package_dir = 14 | = src 15 | packages = find: 16 | python_requires = >=2.7 17 | 18 | [options.packages.find] 19 | where = src 20 | -------------------------------------------------------------------------------- /package/deploy: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ -z "${S3_BUCKET_NAME}" ]; then 5 | echo "S3_BUCKET_NAME is not set" 6 | exit 1 7 | fi 8 | 9 | cd ./package/opt 10 | zip -r package.zip . 11 | mv package.zip .. 12 | cd .. 13 | 14 | sam package \ 15 | --template-file "template.yml" \ 16 | --output-template-file "packaged.yaml" \ 17 | --s3-bucket "${S3_BUCKET_NAME}" 18 | 19 | sam deploy \ 20 | --template-file "packaged.yaml" \ 21 | --stack-name "crypteia-layer" \ 22 | --capabilities CAPABILITY_IAM 23 | -------------------------------------------------------------------------------- /Cargo.toml: -------------------------------------------------------------------------------- 1 | [package] 2 | name = "crypteia" 3 | version = "2.0.0" 4 | edition = "2021" 5 | 6 | [[bin]] 7 | name = "crypteia" 8 | 9 | [lib] 10 | name = "crypteia" 11 | crate-type = ["cdylib"] 12 | 13 | [dependencies] 14 | # bin 15 | anyhow = "1.0.86" 16 | tokio = { version = "1.38.0", features = ["full"] } 17 | futures = { version = "0.3.30" } 18 | aws-config = "1.5.1" 19 | aws-sdk-ssm = "1.34.0" 20 | lambda-extension = "0.10.0" 21 | # lib 22 | redhook = "2.0" 23 | libc = "0.2.155" 24 | lazy_static = "1.4.0" 25 | # both 26 | serde_json = "1.0.117" 27 | 28 | [profile.release] 29 | strip = true 30 | -------------------------------------------------------------------------------- /amzn2023/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/amazonlinux/amazonlinux:2023 2 | 3 | # Install required build dependencies and Node.js for testing 4 | RUN dnf install -y gcc openssl-devel python3-pip util-linux nodejs && \ 5 | pip3 install setuptools && \ 6 | dnf clean all 7 | 8 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 9 | ENV PATH="/root/.cargo/bin:${PATH}" 10 | 11 | RUN /root/.cargo/bin/rustup update \ 12 | && /root/.cargo/bin/rustup target add aarch64-unknown-linux-gnu \ 13 | && /root/.cargo/bin/rustup default stable 14 | 15 | WORKDIR /var/task 16 | 17 | ENV CRYPTEIA_BUILD_OS=amzn 18 | ENV CRYPTEIA_BUILD_TARGET=x86_64-unknown-linux-gnu 19 | 20 | -------------------------------------------------------------------------------- /amzn2023/Dockerfile-arm64: -------------------------------------------------------------------------------- 1 | FROM public.ecr.aws/amazonlinux/amazonlinux:2023 2 | 3 | # Install required build dependencies and Node.js for testing 4 | RUN dnf install -y gcc openssl-devel python3-pip util-linux nodejs && \ 5 | pip3 install setuptools && \ 6 | dnf clean all 7 | 8 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 9 | ENV PATH="/root/.cargo/bin:${PATH}" 10 | 11 | RUN /root/.cargo/bin/rustup update \ 12 | && /root/.cargo/bin/rustup target add aarch64-unknown-linux-gnu \ 13 | && /root/.cargo/bin/rustup default stable 14 | 15 | WORKDIR /var/task 16 | 17 | ENV CRYPTEIA_BUILD_OS=amzn 18 | ENV CRYPTEIA_BUILD_TARGET=aarch64-unknown-linux-gnu 19 | -------------------------------------------------------------------------------- /amzn/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn/Dockerfile] sam/build bin/test ==" 5 | docker run \ 6 | --rm \ 7 | --user root \ 8 | --entrypoint "./test/libcrypteia.sh" \ 9 | --volume "${PWD}:/var/task" \ 10 | --env TEST_LANG=node \ 11 | crypteia-lambda-nodejs 12 | 13 | echo "== [amzn/Dockerfile-test] lambda/runtime building... ==" 14 | docker build --tag crypteia-lambda-nodejs-test --file amzn/Dockerfile-test . 15 | 16 | echo "== [amzn/Dockerfile-test] lambda/runtime bin/test ==" 17 | docker run \ 18 | --rm \ 19 | --user root \ 20 | --entrypoint "./test/libcrypteia.sh" \ 21 | --volume "${PWD}:/var/task" \ 22 | --env TEST_LANG=node \ 23 | crypteia-lambda-nodejs-test 24 | -------------------------------------------------------------------------------- /py27/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | ENV DEBIAN_FRONTEND=noninteractive 4 | 5 | RUN apt update && apt-get install -y \ 6 | curl \ 7 | gcc \ 8 | libssl-dev \ 9 | python3-pip \ 10 | pkg-config \ 11 | zip \ 12 | && rm -rf /var/lib/apt/lists/* 13 | 14 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 15 | ENV PATH="/root/.cargo/bin:${PATH}" 16 | 17 | RUN /root/.cargo/bin/rustup update \ 18 | && /root/.cargo/bin/rustup target add aarch64-unknown-linux-gnu \ 19 | && /root/.cargo/bin/rustup default stable 20 | 21 | WORKDIR /var/task 22 | 23 | ENV CRYPTEIA_BUILD_OS=debian 24 | ENV CRYPTEIA_BUILD_TARGET=x86_64-unknown-linux-gnu 25 | 26 | -------------------------------------------------------------------------------- /amzn2023/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn2023/Dockerfile] bin/test ==" 5 | docker run \ 6 | --rm \ 7 | --user root \ 8 | --entrypoint "./test/libcrypteia.sh" \ 9 | --volume "${PWD}:/var/task" \ 10 | --env TEST_LANG=node \ 11 | crypteia-lambda-amzn2023 12 | 13 | echo "== [amzn2023/Dockerfile-test] lambda/runtime building... ==" 14 | docker build --tag crypteia-lambda-amzn2023-test --file amzn2023/Dockerfile-test . 15 | 16 | echo "== [amzn2023/Dockerfile-test] lambda/runtime bin/test ==" 17 | docker run \ 18 | --rm \ 19 | --user root \ 20 | --entrypoint "./test/libcrypteia.sh" \ 21 | --volume "${PWD}:/var/task" \ 22 | --env TEST_LANG=node \ 23 | crypteia-lambda-amzn2023-test 24 | 25 | -------------------------------------------------------------------------------- /debian/Dockerfile-arm64: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/typescript-node:22-bookworm 2 | 3 | RUN apt update && apt-get install -y python3-pip && rm -rf /var/lib/apt/lists/* 4 | RUN update-alternatives --install /usr/bin/python python /usr/bin/python3 1 5 | RUN update-alternatives --install /usr/bin/pip pip /usr/bin/pip3 1 6 | 7 | RUN curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh -s -- -y 8 | ENV PATH="/root/.cargo/bin:${PATH}" 9 | 10 | RUN /root/.cargo/bin/rustup update \ 11 | && /root/.cargo/bin/rustup target add aarch64-unknown-linux-gnu 12 | RUN rustup default stable 13 | RUN mkdir /var/task 14 | WORKDIR /var/task 15 | 16 | ENV CRYPTEIA_BUILD_OS=debian 17 | ENV CRYPTEIA_BUILD_TARGET=aarch64-unknown-linux-gnu 18 | -------------------------------------------------------------------------------- /bin/build: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Sync with bin/build, bin/test, & test/libcrypteia.sh. 5 | export CRYPTEIA_BUILD_OS="${CRYPTEIA_BUILD_OS:=debian}" 6 | 7 | # Auto-detect build target if not already set 8 | if [ -z "${CRYPTEIA_BUILD_TARGET}" ]; then 9 | case "$(uname -m)" in 10 | aarch64) 11 | export CRYPTEIA_BUILD_TARGET="aarch64-unknown-linux-gnu" 12 | ;; 13 | x86_64) 14 | export CRYPTEIA_BUILD_TARGET="x86_64-unknown-linux-gnu" 15 | ;; 16 | *) 17 | echo "Unsupported architecture: $(uname -m)" 18 | exit 1 19 | ;; 20 | esac 21 | fi 22 | 23 | if [ "${CRYPTEIA_BUILD_TARGET}" = "aarch64-unknown-linux-gnu" ]; then 24 | export CRYPTEIA_BUILD_SUFFIX="-arm64" 25 | fi 26 | 27 | ./bin/build-arch 28 | -------------------------------------------------------------------------------- /amzn/test-arm64: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn/Dockerfile-arm64] sam/build bin/test ==" 5 | docker run \ 6 | --rm \ 7 | --user root \ 8 | --entrypoint "./test/libcrypteia.sh" \ 9 | --volume "${PWD}:/var/task" \ 10 | --env TEST_LANG=node \ 11 | --platform=linux/arm64 \ 12 | crypteia-lambda-nodejs-arm64 13 | 14 | echo "== [amzn/Dockerfile-test-arm64] lambda/runtime building... ==" 15 | docker build --tag crypteia-lambda-nodejs-test-arm64 --file amzn/Dockerfile-test-arm64 . 16 | 17 | echo "== [amzn/Dockerfile-test-arm64] lambda/runtime bin/test ==" 18 | docker run \ 19 | --rm \ 20 | --user root \ 21 | --entrypoint "./test/libcrypteia.sh" \ 22 | --volume "${PWD}:/var/task" \ 23 | --env TEST_LANG=node \ 24 | crypteia-lambda-nodejs-test-arm64 25 | -------------------------------------------------------------------------------- /amzn2023/test-arm64: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | echo "== [amzn2023/Dockerfile-arm64] bin/test ==" 5 | docker run \ 6 | --rm \ 7 | --user root \ 8 | --entrypoint "./test/libcrypteia.sh" \ 9 | --volume "${PWD}:/var/task" \ 10 | --env TEST_LANG=node \ 11 | --platform=linux/arm64 \ 12 | crypteia-lambda-amzn2023-arm64 13 | 14 | echo "== [amzn2023/Dockerfile-test-arm64] lambda/runtime building... ==" 15 | docker build --tag crypteia-lambda-amzn2023-test-arm64 --file amzn2023/Dockerfile-test-arm64 . 16 | 17 | echo "== [amzn2023/Dockerfile-test-arm64] lambda/runtime bin/test ==" 18 | docker run \ 19 | --rm \ 20 | --user root \ 21 | --entrypoint "./test/libcrypteia.sh" \ 22 | --volume "${PWD}:/var/task" \ 23 | --env TEST_LANG=node \ 24 | crypteia-lambda-amzn2023-test-arm64 25 | -------------------------------------------------------------------------------- /package/template.yml: -------------------------------------------------------------------------------- 1 | AWSTemplateFormatVersion: "2010-09-09" 2 | Transform: AWS::Serverless-2016-10-31 3 | Description: Crypteia Lambda Layer https://github.com/rails-lambda/crypteia 4 | Resources: 5 | CryptiaLayer: 6 | Type: AWS::Serverless::LayerVersion 7 | Properties: 8 | LayerName: crypteia 9 | Description: Rust Lambda Extension for any Runtime to preload SSM Parameters as Secure Environment Variables! 10 | ContentUri: package.zip 11 | CompatibleArchitectures: 12 | - x86_64 13 | CompatibleRuntimes: 14 | - nodejs16.x 15 | - nodejs14.x 16 | - nodejs12.x 17 | - python3.9 18 | - python3.8 19 | - python3.7 20 | - java11 21 | - java8.al2 22 | - ruby2.7 23 | - dotnet6 24 | - dotnetcore3.1 25 | - provided.al2 26 | RetentionPolicy: Delete 27 | LicenseInfo: MIT 28 | -------------------------------------------------------------------------------- /python/usercustomize.py: -------------------------------------------------------------------------------- 1 | # Trigger the load of the Crypteia python package, 2 | # that is going to apply wrapt to the os.environ object, 3 | # so that we can customize the lookup of the environment 4 | # variables at runtime. We cannot do this in LD_PRELOAD, 5 | # because CPython uses LibC to look up only the PYTHON* 6 | # environment variables, parsing directly the memory 7 | # resolved by the linker to the __environ symbol as a 8 | # Unix dictionary. 9 | 10 | # IMPORTANT: This file must be valid Python 2.7+ 11 | 12 | from os.path import dirname 13 | from sys import path, version, version_info 14 | 15 | 16 | def import_crypteia(): 17 | current_site = dirname(__file__) 18 | 19 | # We cannot use `sys.version_info.major` and other named attribute 20 | # got introduced only in Python 3.1 21 | if version_info[0] == 2 and version_info[1] < 7: 22 | path.remove(current_site) 23 | print("#CRYPTEIA# - Cannot import 'crypteia' due unsupported runtime version: {}".format(version)) 24 | return 25 | 26 | import crypteia 27 | 28 | 29 | import_crypteia() 30 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "crypteia", 3 | "build": { 4 | "dockerfile": "Dockerfile" 5 | }, 6 | "features": { 7 | "ghcr.io/devcontainers/features/aws-cli:latest": {}, 8 | "ghcr.io/devcontainers/features/docker-in-docker:latest": { 9 | "install-qemu": false 10 | }, 11 | "ghcr.io/customink/codespaces-features/docker-log-level": {}, 12 | "ghcr.io/devcontainers/features/sshd:latest": {} 13 | }, 14 | "customizations": { 15 | "vscode": { 16 | "settings": { 17 | "editor.formatOnSave": true, 18 | "lldb.executable": "/usr/bin/lldb", 19 | "files.watcherExclude": { 20 | "**/target/**": true 21 | }, 22 | "rust-analyzer.checkOnSave.command": "clippy" 23 | }, 24 | "extensions": [ 25 | "vadimcn.vscode-lldb", 26 | "mutantdino.resourcemonitor", 27 | "rust-lang.rust-analyzer", 28 | "tamasfe.even-better-toml", 29 | "serayuzgur.crates" 30 | ] 31 | } 32 | }, 33 | "postCreateCommand": "./.devcontainer/postCreate", 34 | "remoteUser": "vscode" 35 | } 36 | -------------------------------------------------------------------------------- /py27/Dockerfile-test: -------------------------------------------------------------------------------- 1 | FROM ubuntu:22.04 2 | 3 | ENV SHELL=/bin/sh 4 | 5 | RUN apt-get update && apt-get install -y software-properties-common && add-apt-repository ppa:deadsnakes/ppa && apt-get update 6 | RUN apt-get install -y --no-install-recommends \ 7 | ca-certificates \ 8 | curl \ 9 | util-linux \ 10 | file \ 11 | binutils \ 12 | python2.7 \ 13 | python2.7-dev \ 14 | && update-alternatives --install /usr/bin/python python /usr/bin/python2.7 2 15 | 16 | RUN curl https://bootstrap.pypa.io/pip/2.7/get-pip.py --output get-pip.py \ 17 | && python get-pip.py \ 18 | && pip install --upgrade pip \ 19 | && apt-get clean \ 20 | && rm -rf /var/lib/apt/lists/* /tmp/* /var/tmp/* 21 | 22 | COPY build/crypteia-debian /opt/extensions/crypteia 23 | COPY build/libcrypteia-debian.so /opt/lib/libcrypteia.so 24 | COPY package/opt/crypteia /opt/crypteia 25 | 26 | WORKDIR /var/task 27 | 28 | ENV CRYPTEIA_BUILD_OS=debian 29 | ENV SKIP_CARGO_TEST=1 30 | 31 | ENV EXISTING=existingvalue 32 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 33 | ENV PYTHONPATH=/opt/crypteia/python 34 | -------------------------------------------------------------------------------- /src/log.rs: -------------------------------------------------------------------------------- 1 | use serde_json::json; 2 | use std::time::SystemTime; 3 | use std::time::UNIX_EPOCH; 4 | 5 | pub fn cloudwatch_metric(dimension: &str, name: &str, error: bool, error_message: Option) { 6 | let timestamp = SystemTime::now() 7 | .duration_since(UNIX_EPOCH) 8 | .unwrap() 9 | .as_millis() 10 | .to_string() 11 | .parse::() 12 | .unwrap(); 13 | let metric = serde_json::to_string(&json!( 14 | { 15 | "_aws": { 16 | "Timestamp": timestamp, 17 | "CloudWatchMetrics": [ 18 | { 19 | "Namespace": "Crypteia", 20 | "Dimensions": [["All", dimension]], 21 | "Metrics": [ 22 | { "Name": name, "Unit": "Count"} 23 | ] 24 | } 25 | ] 26 | }, 27 | "All": "all", 28 | dimension: dimension, 29 | name: 1, 30 | "ErrorMessage": error_message.unwrap_or("".to_string()), 31 | } 32 | )) 33 | .unwrap(); 34 | if error { 35 | eprintln!("{}", metric); 36 | } else { 37 | println!("{}", metric); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /bin/test: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # Sync with bin/build, bin/test, & test/libcrypteia.sh. 5 | export CRYPTEIA_BUILD_OS="${CRYPTEIA_BUILD_OS:=debian}" 6 | 7 | # Auto-detect build target if not already set 8 | if [ -z "${CRYPTEIA_BUILD_TARGET}" ]; then 9 | case "$(uname -m)" in 10 | aarch64) 11 | export CRYPTEIA_BUILD_TARGET="aarch64-unknown-linux-gnu" 12 | ;; 13 | x86_64) 14 | export CRYPTEIA_BUILD_TARGET="x86_64-unknown-linux-gnu" 15 | ;; 16 | *) 17 | echo "Unsupported architecture: $(uname -m)" >&2 18 | exit 1 19 | ;; 20 | esac 21 | fi 22 | 23 | if [ "${CRYPTEIA_BUILD_TARGET}" = "aarch64-unknown-linux-gnu" ]; then 24 | export CRYPTEIA_BUILD_SUFFIX="-arm64" 25 | fi 26 | 27 | if [ ! "${SKIP_CARGO_TEST}" = "1" ]; then 28 | cargo test --target "${CRYPTEIA_BUILD_TARGET}" --quiet 29 | fi 30 | 31 | # Language runtime tests now work on both architectures thanks to proper 32 | # LD_PRELOAD path matching (CRYPTEIA_BUILD_SUFFIX) and installed runtimes 33 | TEST_LANG=node ./test/libcrypteia.sh 34 | TEST_LANG=ruby ./test/libcrypteia.sh 35 | TEST_LANG=php ./test/libcrypteia.sh 36 | TEST_LANG=python ./test/libcrypteia.sh 37 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Ken Collins, 4 | Copyright (c) 2022 Jake Scott, 5 | 6 | Permission is hereby granted, free of charge, to any person obtaining a copy 7 | of this software and associated documentation files (the "Software"), to deal 8 | in the Software without restriction, including without limitation the rights 9 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 10 | copies of the Software, and to permit persons to whom the Software is 11 | furnished to do so, subject to the following conditions: 12 | 13 | The above copyright notice and this permission notice shall be included in all 14 | copies or substantial portions of the Software. 15 | 16 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 17 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 18 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 19 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 20 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 21 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 22 | SOFTWARE. 23 | -------------------------------------------------------------------------------- /src/main.rs: -------------------------------------------------------------------------------- 1 | mod log; 2 | mod ssm; 3 | use lambda_extension::{service_fn, Error, LambdaEvent, NextEvent}; 4 | use std::collections::HashMap; 5 | use std::fs::File; 6 | use std::io::Write; 7 | 8 | const ENV_FILE: &str = "/tmp/crypteia.json"; 9 | 10 | #[tokio::main] 11 | async fn main() -> Result<(), Error> { 12 | log::cloudwatch_metric("main", "initialized", false, None); 13 | let env_vars: HashMap = std::env::vars().collect(); 14 | let env_map = ssm::get_envs(env_vars).await.unwrap(); 15 | log::cloudwatch_metric("main", "fetched", false, None); 16 | write_envs_to_tmp_json(env_map); 17 | let func = service_fn(parameters_extension); 18 | lambda_extension::run(func).await 19 | } 20 | 21 | async fn parameters_extension(event: LambdaEvent) -> Result<(), Error> { 22 | match event.next { 23 | NextEvent::Shutdown(_e) => { 24 | log::cloudwatch_metric("main", "shutdown", false, None); 25 | } 26 | NextEvent::Invoke(_e) => {} 27 | } 28 | Ok(()) 29 | } 30 | 31 | fn write_envs_to_tmp_json(env_map: HashMap) { 32 | let envs_json = serde_json::to_string(&env_map).unwrap(); 33 | let mut file = File::create(ENV_FILE).unwrap(); 34 | file.write_all(envs_json.as_bytes()).unwrap(); 35 | } -------------------------------------------------------------------------------- /python/crypteia/src/crypteia/__init__.py: -------------------------------------------------------------------------------- 1 | import ctypes 2 | import os 3 | import sys 4 | 5 | from crypteia.wrapt import ObjectProxy, register_post_import_hook, wrap_object 6 | 7 | PY2 = sys.version_info[0] == 2 8 | 9 | crypteia = os.environ.get("LD_PRELOAD") 10 | getenv = ctypes.cdll.LoadLibrary(crypteia).getenv 11 | getenv.restype = ctypes.c_char_p 12 | 13 | 14 | class GetEnvWrapper(ObjectProxy): 15 | def __getitem__(self, key): 16 | if PY2: 17 | value = getenv(key) 18 | else: 19 | encodedkey = self.__wrapped__.encodekey(key) 20 | value = getenv(encodedkey) 21 | if value: 22 | value = self.__wrapped__.decodevalue(value) 23 | 24 | if value: 25 | return value 26 | else: 27 | raise KeyError(key) 28 | 29 | def __repr__(self): 30 | if PY2: 31 | return repr(self.__wrapped__.data) 32 | else: 33 | return repr(self.__wrapped__) 34 | 35 | def get(self, key, default=None): 36 | try: 37 | item = self[key] 38 | except KeyError: 39 | return default 40 | 41 | return item 42 | 43 | 44 | def _load_and_patch(module): 45 | wrap_object(module, 'environ', GetEnvWrapper) 46 | 47 | 48 | register_post_import_hook(_load_and_patch, 'os') 49 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM mcr.microsoft.com/devcontainers/rust:1-1-bookworm 2 | 3 | RUN apt-get update -y \ 4 | && apt-get upgrade -y \ 5 | && apt-get install -y --fix-missing --no-install-recommends \ 6 | \ 7 | # Zip for packaging 8 | zip \ 9 | \ 10 | # QEMU for multi-architecture support 11 | qemu-system \ 12 | binfmt-support \ 13 | qemu-user-static \ 14 | \ 15 | # Language runtimes for tests 16 | nodejs \ 17 | ruby \ 18 | php \ 19 | php-common \ 20 | python3-pip \ 21 | \ 22 | # Cross-compilation toolchains 23 | gcc-x86-64-linux-gnu \ 24 | libc6-dev-amd64-cross \ 25 | gcc-aarch64-linux-gnu \ 26 | libc6-dev-arm64-cross \ 27 | \ 28 | # Clean up, enable QEMU, and set Python alternative in a single layer 29 | && rm -rf /var/lib/apt/lists/* \ 30 | && update-binfmts --enable qemu-aarch64 \ 31 | && update-alternatives --install /usr/bin/python python /usr/bin/python3 1 32 | 33 | # Switch to root to install rust targets and fix permissions 34 | USER root 35 | 36 | # Install rust targets for cross-compilation 37 | RUN rustup update \ 38 | && rustup default stable \ 39 | && rustup target add aarch64-unknown-linux-gnu \ 40 | && rustup target add x86_64-unknown-linux-gnu 41 | 42 | # Grant vscode user ownership of rustup and cargo directories 43 | RUN chown -R vscode:vscode /usr/local/rustup /usr/local/cargo 44 | 45 | # Switch back to vscode user 46 | USER vscode 47 | 48 | # Multi-platform SAM CLI. https://github.com/aws/aws-sam-cli/issues/3908 49 | RUN pip install aws-sam-cli --break-system-packages 50 | -------------------------------------------------------------------------------- /package/deploy-image-amzn: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ -z "${CRYPTEIA_VERSION}" ]; then 5 | echo "CRYPTEIA_VERSION is not set" 6 | exit 1 7 | fi 8 | 9 | CRYPTEIA_VERSION_MAJOR=$(echo "${CRYPTEIA_VERSION}" | cut -d. -f1) 10 | 11 | docker login ghcr.io -u "metaskills" -p $DOCKER_LOGIN_PAT 12 | 13 | ./amzn/setup 14 | BASE_NAME_AMD64="ghcr.io/rails-lambda/crypteia-extension-amzn-amd64" 15 | docker build \ 16 | --platform linux/amd64 \ 17 | --tag "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION_MAJOR}" \ 18 | --tag "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION}" \ 19 | --file package/Dockerfile . 20 | docker push "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION_MAJOR}" 21 | docker push "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION}" 22 | 23 | ./amzn/setup-arm64 24 | BASE_NAME_ARM64="ghcr.io/rails-lambda/crypteia-extension-amzn-arm64" 25 | docker build \ 26 | --platform linux/arm64 \ 27 | --tag "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION_MAJOR}" \ 28 | --tag "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION}" \ 29 | --file package/Dockerfile . 30 | docker push "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION_MAJOR}" 31 | docker push "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION}" 32 | 33 | docker manifest create \ 34 | "ghcr.io/rails-lambda/crypteia-extension-amzn:${CRYPTEIA_VERSION_MAJOR}" \ 35 | --amend "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION_MAJOR}" \ 36 | --amend "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION_MAJOR}" 37 | docker manifest push "ghcr.io/rails-lambda/crypteia-extension-amzn:${CRYPTEIA_VERSION_MAJOR}" 38 | 39 | docker manifest create \ 40 | "ghcr.io/rails-lambda/crypteia-extension-amzn:${CRYPTEIA_VERSION}" \ 41 | --amend "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION}" \ 42 | --amend "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION}" 43 | docker manifest push "ghcr.io/rails-lambda/crypteia-extension-amzn:${CRYPTEIA_VERSION}" 44 | -------------------------------------------------------------------------------- /package/deploy-image-debian: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | if [ -z "${CRYPTEIA_VERSION}" ]; then 5 | echo "CRYPTEIA_VERSION is not set" 6 | exit 1 7 | fi 8 | 9 | CRYPTEIA_VERSION_MAJOR=$(echo "${CRYPTEIA_VERSION}" | cut -d. -f1) 10 | 11 | docker login ghcr.io -u "metaskills" -p $DOCKER_LOGIN_PAT 12 | 13 | ./bin/setup 14 | BASE_NAME_AMD64="ghcr.io/rails-lambda/crypteia-extension-debian-amd64" 15 | docker build \ 16 | --platform linux/amd64 \ 17 | --tag "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION_MAJOR}" \ 18 | --tag "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION}" \ 19 | --file package/Dockerfile . 20 | docker push "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION_MAJOR}" 21 | docker push "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION}" 22 | 23 | ./debian/setup-arm64 24 | BASE_NAME_ARM64="ghcr.io/rails-lambda/crypteia-extension-debian-arm64" 25 | docker build \ 26 | --platform linux/arm64 \ 27 | --tag "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION_MAJOR}" \ 28 | --tag "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION}" \ 29 | --file package/Dockerfile . 30 | docker push "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION_MAJOR}" 31 | docker push "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION}" 32 | 33 | docker manifest create \ 34 | "ghcr.io/rails-lambda/crypteia-extension-debian:${CRYPTEIA_VERSION_MAJOR}" \ 35 | --amend "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION_MAJOR}" \ 36 | --amend "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION_MAJOR}" 37 | docker manifest push "ghcr.io/rails-lambda/crypteia-extension-debian:${CRYPTEIA_VERSION_MAJOR}" 38 | 39 | docker manifest create \ 40 | "ghcr.io/rails-lambda/crypteia-extension-debian:${CRYPTEIA_VERSION}" \ 41 | --amend "${BASE_NAME_AMD64}:${CRYPTEIA_VERSION}" \ 42 | --amend "${BASE_NAME_ARM64}:${CRYPTEIA_VERSION}" 43 | docker manifest push "ghcr.io/rails-lambda/crypteia-extension-debian:${CRYPTEIA_VERSION}" 44 | -------------------------------------------------------------------------------- /test/libcrypteia.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | . ./test/assert.sh 4 | 5 | # Sync with bin/build, bin/test, & test/libcrypteia.sh. 6 | export CRYPTEIA_BUILD_OS="${CRYPTEIA_BUILD_OS:=debian}" 7 | export CRYPTEIA_BUILD_TARGET="${CRYPTEIA_BUILD_TARGET:=x86_64-unknown-linux-gnu}" 8 | if [ "${CRYPTEIA_BUILD_TARGET}" = "aarch64-unknown-linux-gnu" ]; then 9 | export CRYPTEIA_BUILD_SUFFIX="-arm64" 10 | fi 11 | 12 | export CRYPTEIA_ENV_FILE="/tmp/crypteia.json" 13 | export TEST_LANG="${TEST_LANG:=node}" 14 | export LD_PRELOAD="${LD_PRELOAD:=$PWD/build/libcrypteia-${CRYPTEIA_BUILD_OS}${CRYPTEIA_BUILD_SUFFIX}.so}" 15 | export PYTHONPATH="${PYTHONPATH:=$PWD/package/opt/crypteia/python}" 16 | 17 | echo "=============================" 18 | echo " TEST_LANG: ${TEST_LANG}" 19 | echo "=============================" 20 | 21 | echo "== Simulating crypteia binary JSON write ==" 22 | echo '{ 23 | "SECRET": "1A2B3C4D5E6F", 24 | "ACCESS_KEY": "G7H8I9J0K1L2", 25 | "DB_URL": "mysql2://u:p@host:3306", 26 | "NR_KEY": "z6y5x4w3v2u1" 27 | }' > $CRYPTEIA_ENV_FILE 28 | 29 | echo "== Testing libcrypteia ==" 30 | 31 | assert "./test/libcrypteia/_envfile.sh" \ 32 | "PRESENT" 33 | 34 | assert "./test/libcrypteia/existing-${TEST_LANG}.sh" \ 35 | "existingvalue" 36 | 37 | assert "./test/libcrypteia/_envfile.sh" \ 38 | "PRESENT" "Because existing values does not trigger libcrypteia code." 39 | 40 | assert "./test/libcrypteia/override-${TEST_LANG}.sh" \ 41 | "1A2B3C4D5E6F" 42 | 43 | assert "./test/libcrypteia/_envfile.sh" \ 44 | "REMOVED" "Because first x-crypteia access." 45 | 46 | assert "./test/libcrypteia/empty-${TEST_LANG}.sh" \ 47 | "undefined" 48 | 49 | assert "./test/libcrypteia/fullpath-${TEST_LANG}.sh" \ 50 | "x-crypteia-ssm-path:/crypteia/v5/myapp/envs" \ 51 | "Because not replaced by a single env var." 52 | 53 | echo "== Testing complete! ==" 54 | 55 | assert_end examples 56 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Changelog 2 | 3 | All notable changes to this project will be documented in this file. 4 | 5 | The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/), 6 | and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html). 7 | 8 | ## Unreleased 9 | 10 | ## [2.1.0] - 2025-12-02 11 | 12 | ### Added 13 | 14 | - Amazon Linux 2023 support (x86_64 and arm64) 15 | - Architecture auto-detection in build/test scripts 16 | 17 | ### Changed 18 | 19 | - Upgrade dev container from Debian 11 (Bullseye) to Debian 12 (Bookworm) 20 | - Upgrade Debian arm64 test image to Node.js 22 (LTS) 21 | - Update GitHub Actions runners to ubuntu-22.04 22 | - Enable language runtime tests on all architectures 23 | - Pin wrapt to `<1.15.0` for Python 2.7 compatibility 24 | 25 | ### Fixed 26 | 27 | - ARM64 release builds via QEMU emulation setup 28 | - Disk space issues in release workflow 29 | 30 | ## [2.0.0] - 2024-6-12 31 | 32 | - Fix release workflow and update base image 33 | - Update cargo packages 34 | - Improve logging 35 | 36 | ## [1.1.2] - 2023-05-20 37 | 38 | - Simple major version docker tags. Ex: 1 39 | 40 | ## [1.1.0] - 2023-01-18 41 | 42 | - Add arm64 support. 43 | 44 | ## [1.0.0] - 2022-10-26 45 | 46 | ### Added 47 | 48 | - `ltrace` for debugging 49 | - Patch Python's `os.environ` if `PYTHONPATH` is set accordingly. Needed for Crypteia's binary to work in Python environments. 50 | 51 | ### Changed 52 | 53 | - Use `scratch` base instead of `alpine` for smaller lambda extension images. 54 | 55 | ## [0.94.0] - 2022-10-03 56 | 57 | Schedule release. No changes. 58 | 59 | ## [0.90.0] - 2022-06-27 60 | 61 | 🎉 Initial Release! 62 | 63 | ### Added 64 | 65 | - Use `x-crypteia-ssm:` - Single path for a single environment variable. 66 | - Use `x-crypteia-ssm-path:` - Path prefix to fetch many environment variables. 67 | - Binary & Shared Object files for both Debian/Ubuntu/Etc & Amazon Linux 2 68 | -------------------------------------------------------------------------------- /bin/build-arch: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | BIN="crypteia-${CRYPTEIA_BUILD_OS}${CRYPTEIA_BUILD_SUFFIX}" 5 | LIB="libcrypteia-${CRYPTEIA_BUILD_OS}${CRYPTEIA_BUILD_SUFFIX}.so" 6 | 7 | rm -rf ./build 8 | rm -rf ./target 9 | rm -rf ./python/crypteia/build 10 | rm -rf ./python/crypteia/src/crypteia.egg-info 11 | 12 | mkdir -p ./build ./target 13 | 14 | cargo build \ 15 | --release \ 16 | --target "${CRYPTEIA_BUILD_TARGET}" 17 | 18 | cp "./target/${CRYPTEIA_BUILD_TARGET}/release/crypteia" "./build/${BIN}" 19 | cp "./target/${CRYPTEIA_BUILD_TARGET}/release/libcrypteia.so" "./build/${LIB}" 20 | 21 | cd ./build 22 | 23 | # Use appropriate strip command based on target 24 | case "${CRYPTEIA_BUILD_TARGET}" in 25 | aarch64-unknown-linux-gnu) 26 | if [ "$(uname -m)" = "aarch64" ]; then 27 | strip "$BIN" 28 | else 29 | aarch64-linux-gnu-strip "$BIN" 2>/dev/null || strip "$BIN" 30 | fi 31 | ;; 32 | x86_64-unknown-linux-gnu) 33 | if [ "$(uname -m)" = "x86_64" ]; then 34 | strip "$BIN" 35 | else 36 | x86_64-linux-gnu-strip "$BIN" 2>/dev/null || strip "$BIN" 37 | fi 38 | ;; 39 | esac 40 | 41 | chmod +x "$BIN" 42 | zip -r "${BIN}.zip" "$BIN" 43 | zip -r "libcrypteia-${CRYPTEIA_BUILD_OS}${CRYPTEIA_BUILD_SUFFIX}.zip" "$LIB" 44 | cd .. 45 | 46 | rm -rf ./package/opt 47 | mkdir -p ./package/opt/extensions 48 | mkdir -p ./package/opt/lib 49 | cp "./build/crypteia-${CRYPTEIA_BUILD_OS}${CRYPTEIA_BUILD_SUFFIX}" ./package/opt/extensions/crypteia 50 | cp "./build/libcrypteia-${CRYPTEIA_BUILD_OS}${CRYPTEIA_BUILD_SUFFIX}.so" ./package/opt/lib/libcrypteia.so 51 | 52 | cd ./python/crypteia && pip install . --target ../../build --upgrade && cd ../.. 53 | cp ./python/usercustomize.py ./build/ 54 | 55 | mkdir -p ./package/opt/crypteia/python/crypteia 56 | cp -r ./build/crypteia/ ./package/opt/crypteia/python/ 57 | cp -r ./build/crypteia-*.dist-info ./package/opt/crypteia/python/ 58 | cp -r ./build/wrapt/ ./package/opt/crypteia/python/crypteia/ 59 | cp ./python/usercustomize.py ./package/opt/crypteia/python/usercustomize.py 60 | -------------------------------------------------------------------------------- /.github/workflows/release.yml: -------------------------------------------------------------------------------- 1 | name: "Release" 2 | on: 3 | workflow_dispatch: 4 | inputs: 5 | version: 6 | description: "Example: 1.1.0" 7 | required: true 8 | type: string 9 | jobs: 10 | image: 11 | name: Image 12 | runs-on: ubuntu-22.04 13 | steps: 14 | - uses: actions/checkout@v4 15 | - uses: docker/login-action@v2 16 | with: 17 | registry: ghcr.io 18 | username: ${{ github.repository_owner }} 19 | password: ${{ secrets.GITHUB_TOKEN }} 20 | - uses: devcontainers/ci@v0.2 21 | with: 22 | push: always 23 | imageName: ghcr.io/rails-lambda/crypteia-ci 24 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 25 | runCmd: echo DONE! 26 | debian: 27 | name: Debian x86_64/arm64 28 | runs-on: ubuntu-22.04 29 | needs: image 30 | steps: 31 | - uses: actions/checkout@v4 32 | - name: Free Disk Space 33 | uses: jlumbroso/free-disk-space@main 34 | with: 35 | tool-cache: true 36 | docker-images: false 37 | - uses: docker/setup-qemu-action@v3 38 | - uses: devcontainers/ci@v0.2 39 | env: 40 | DOCKER_LOGIN_PAT: ${{ secrets.GITHUB_TOKEN }} 41 | with: 42 | push: never 43 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 44 | env: | 45 | DOCKER_LOGIN_PAT 46 | runCmd: | 47 | CRYPTEIA_VERSION=${{ github.event.inputs.version }} ./package/deploy-image-debian 48 | amzn: 49 | name: AmazonLinux2 x86_64/arm64 50 | runs-on: ubuntu-22.04 51 | needs: image 52 | steps: 53 | - uses: actions/checkout@v4 54 | - name: Free Disk Space 55 | uses: jlumbroso/free-disk-space@main 56 | with: 57 | tool-cache: true 58 | docker-images: false 59 | - uses: docker/setup-qemu-action@v3 60 | - uses: devcontainers/ci@v0.2 61 | env: 62 | DOCKER_LOGIN_PAT: ${{ secrets.GITHUB_TOKEN }} 63 | with: 64 | push: never 65 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 66 | env: | 67 | DOCKER_LOGIN_PAT 68 | runCmd: | 69 | CRYPTEIA_VERSION=${{ github.event.inputs.version }} ./package/deploy-image-amzn 70 | release: 71 | name: Create Release 72 | runs-on: ubuntu-22.04 73 | needs: [debian, amzn] 74 | steps: 75 | - uses: actions/checkout@v4 76 | - name: CHANGELOG Entry 77 | id: changelog_reader 78 | uses: mindsers/changelog-reader-action@v2 79 | with: 80 | validation_level: warn 81 | version: ${{ github.event.inputs.version }} 82 | path: ./CHANGELOG.md 83 | - name: Create Release 84 | uses: ncipollo/release-action@v1 85 | with: 86 | allowUpdates: true 87 | artifacts: false 88 | tag: ${{ steps.changelog_reader.outputs.version }} 89 | name: Release ${{ steps.changelog_reader.outputs.version }} 90 | body: ${{ steps.changelog_reader.outputs.changes }} 91 | prerelease: ${{ steps.changelog_reader.outputs.status == 'prereleased' }} 92 | draft: ${{ steps.changelog_reader.outputs.status == 'unreleased' }} 93 | token: ${{ secrets.GITHUB_TOKEN }} 94 | -------------------------------------------------------------------------------- /CODE_OF_CONDUCT.md: -------------------------------------------------------------------------------- 1 | # Contributor Covenant Code of Conduct 2 | 3 | ## Our Pledge 4 | 5 | In the interest of fostering an open and welcoming environment, we as 6 | contributors and maintainers pledge to making participation in our project and 7 | our community a harassment-free experience for everyone, regardless of age, body 8 | size, disability, ethnicity, gender identity and expression, level of experience, 9 | nationality, personal appearance, race, religion, or sexual identity and 10 | orientation. 11 | 12 | ## Our Standards 13 | 14 | Examples of behavior that contributes to creating a positive environment 15 | include: 16 | 17 | - Using welcoming and inclusive language 18 | - Being respectful of differing viewpoints and experiences 19 | - Gracefully accepting constructive criticism 20 | - Focusing on what is best for the community 21 | - Showing empathy towards other community members 22 | 23 | Examples of unacceptable behavior by participants include: 24 | 25 | - The use of sexualized language or imagery and unwelcome sexual attention or 26 | advances 27 | - Trolling, insulting/derogatory comments, and personal or political attacks 28 | - Public or private harassment 29 | - Publishing others' private information, such as a physical or electronic 30 | address, without explicit permission 31 | - Other conduct which could reasonably be considered inappropriate in a 32 | professional setting 33 | 34 | ## Our Responsibilities 35 | 36 | Project maintainers are responsible for clarifying the standards of acceptable 37 | behavior and are expected to take appropriate and fair corrective action in 38 | response to any instances of unacceptable behavior. 39 | 40 | Project maintainers have the right and responsibility to remove, edit, or 41 | reject comments, commits, code, wiki edits, issues, and other contributions 42 | that are not aligned to this Code of Conduct, or to ban temporarily or 43 | permanently any contributor for other behaviors that they deem inappropriate, 44 | threatening, offensive, or harmful. 45 | 46 | ## Scope 47 | 48 | This Code of Conduct applies both within project spaces and in public spaces 49 | when an individual is representing the project or its community. Examples of 50 | representing a project or community include using an official project e-mail 51 | address, posting via an official social media account, or acting as an appointed 52 | representative at an online or offline event. Representation of a project may be 53 | further defined and clarified by project maintainers. 54 | 55 | ## Enforcement 56 | 57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be 58 | reported by contacting the project team at ken@metaskills.net. All 59 | complaints will be reviewed and investigated and will result in a response that 60 | is deemed necessary and appropriate to the circumstances. The project team is 61 | obligated to maintain confidentiality with regard to the reporter of an incident. 62 | Further details of specific enforcement policies may be posted separately. 63 | 64 | Project maintainers who do not follow or enforce the Code of Conduct in good 65 | faith may face temporary or permanent repercussions as determined by other 66 | members of the project's leadership. 67 | 68 | ## Attribution 69 | 70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4, 71 | available at [http://contributor-covenant.org/version/1/4][version] 72 | 73 | [homepage]: http://contributor-covenant.org 74 | [version]: http://contributor-covenant.org/version/1/4/ 75 | -------------------------------------------------------------------------------- /src/lib.rs: -------------------------------------------------------------------------------- 1 | extern crate libc; 2 | mod log; 3 | use lazy_static::lazy_static; 4 | use libc::c_char; 5 | use std::collections::HashMap; 6 | use std::env::vars_os; 7 | use std::ffi::{CStr, CString}; 8 | use std::fs::{metadata, remove_file, File}; 9 | use std::io::Read; 10 | use std::sync::atomic::{AtomicBool, Ordering}; 11 | use std::sync::{Mutex, Once}; 12 | 13 | static mut DEBUG: bool = false; 14 | static INITIALIZATION: Once = Once::new(); 15 | 16 | const ENV_FILE: &str = "/tmp/crypteia.json"; 17 | static ENV_FILE_READ: AtomicBool = AtomicBool::new(false); 18 | lazy_static! { 19 | static ref CRYPTEIA_ENVS: Mutex> = Mutex::new(HashMap::new()); 20 | } 21 | 22 | redhook::hook! { 23 | unsafe fn getenv(name: *const c_char) -> *mut c_char => crypteia_getenv { 24 | INITIALIZATION.call_once(|| { 25 | for (key, _value) in vars_os() { 26 | if let Some("CRYPTEIA_DEBUG") = key.to_str() { 27 | DEBUG = true; 28 | } 29 | } 30 | if DEBUG { 31 | log::cloudwatch_metric("lib", "initialized", false, None); 32 | } 33 | }); 34 | let env_value = redhook::real!(getenv)(name); 35 | if env_value.is_null() { 36 | return env_value; 37 | } 38 | let env_value_str = CStr::from_ptr(env_value).to_str().unwrap(); 39 | let env_value_string = env_value_str.to_string(); 40 | if env_value_string.starts_with("x-crypteia") { 41 | let name_str = CStr::from_ptr(name).to_str().unwrap(); 42 | let name_string = name_str.to_string(); 43 | if is_env_file_read() { 44 | match crypteia_env_value(name_string) { 45 | Some(value) => value, 46 | None => env_value 47 | } 48 | } else if is_env_file() { 49 | read_env_file(); 50 | match crypteia_env_value(name_string) { 51 | Some(value) => value, 52 | None => env_value 53 | } 54 | } else { 55 | env_value 56 | } 57 | } else { 58 | env_value 59 | } 60 | } 61 | } 62 | 63 | fn crypteia_env_value(env: String) -> Option<*mut c_char> { 64 | if CRYPTEIA_ENVS.lock().unwrap().contains_key(&env) { 65 | let crypteia_value = CRYPTEIA_ENVS.lock().unwrap().get(&env).unwrap().clone(); 66 | let crypteia_value_c_string = CString::new(crypteia_value).unwrap(); 67 | Some(crypteia_value_c_string.into_raw()) 68 | } else { 69 | None 70 | } 71 | } 72 | 73 | fn is_env_file() -> bool { 74 | let boo_value = metadata(ENV_FILE).is_ok(); 75 | unsafe { 76 | if DEBUG { 77 | log::cloudwatch_metric("lib", "is_env_file", false, None); 78 | } 79 | } 80 | boo_value 81 | } 82 | 83 | fn is_env_file_read() -> bool { 84 | ENV_FILE_READ.load(Ordering::Relaxed) 85 | } 86 | 87 | fn read_env_file() { 88 | let mut file = File::open(ENV_FILE).unwrap(); 89 | let mut contents = String::new(); 90 | file.read_to_string(&mut contents).unwrap(); 91 | let crypteia_envs: HashMap = serde_json::from_str(&contents).unwrap(); 92 | crypteia_envs.iter().for_each(|(env, value)| { 93 | CRYPTEIA_ENVS 94 | .lock() 95 | .unwrap() 96 | .insert(env.clone(), value.clone()); 97 | }); 98 | unsafe { 99 | if DEBUG { 100 | log::cloudwatch_metric("lib", "read_env_file", false, None); 101 | } 102 | } 103 | delete_file(); 104 | ENV_FILE_READ.store(true, Ordering::Relaxed); 105 | } 106 | 107 | fn delete_file() { 108 | remove_file(ENV_FILE).unwrap(); 109 | unsafe { 110 | if DEBUG { 111 | log::cloudwatch_metric("lib", "delete_file", false, None); 112 | } 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /.github/workflows/test.yml: -------------------------------------------------------------------------------- 1 | name: Test 2 | on: [push, workflow_dispatch] 3 | jobs: 4 | image: 5 | name: Image 6 | runs-on: ubuntu-22.04 7 | steps: 8 | - uses: actions/checkout@v4 9 | - uses: docker/login-action@v2 10 | with: 11 | registry: ghcr.io 12 | username: ${{ github.repository_owner }} 13 | password: ${{ secrets.GITHUB_TOKEN }} 14 | - uses: devcontainers/ci@v0.2 15 | with: 16 | push: always 17 | imageName: ghcr.io/rails-lambda/crypteia-ci 18 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 19 | runCmd: echo DONE! 20 | debian-x86-64: 21 | name: Debian x86_64 22 | runs-on: ubuntu-22.04 23 | needs: image 24 | steps: 25 | - name: Checkout 26 | uses: actions/checkout@v4 27 | - name: Test 28 | uses: devcontainers/ci@v0.2 29 | with: 30 | push: never 31 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 32 | runCmd: | 33 | ./bin/setup 34 | ./bin/test-local 35 | debian-arm64: 36 | name: Debian arm64 37 | runs-on: ubuntu-22.04 38 | needs: image 39 | steps: 40 | - name: Checkout 41 | uses: actions/checkout@v4 42 | - name: Set up QEMU 43 | uses: docker/setup-qemu-action@v3 44 | - name: Set up Docker Buildx 45 | uses: docker/setup-buildx-action@v3 46 | - name: Test 47 | uses: devcontainers/ci@v0.2 48 | with: 49 | push: never 50 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 51 | runCmd: | 52 | ./debian/setup-arm64 53 | ./debian/test-arm64 54 | amazon-x86-64: 55 | name: AmazonLinux2/x86_64 56 | runs-on: ubuntu-22.04 57 | needs: image 58 | steps: 59 | - name: Checkout 60 | uses: actions/checkout@v4 61 | - name: Test 62 | uses: devcontainers/ci@v0.2 63 | with: 64 | push: never 65 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 66 | runCmd: | 67 | ./amzn/setup 68 | ./amzn/test 69 | amazon-arm64: 70 | name: AmazonLinux2 arm64 71 | runs-on: ubuntu-22.04 72 | needs: image 73 | steps: 74 | - name: Checkout 75 | uses: actions/checkout@v4 76 | - name: Set up QEMU 77 | uses: docker/setup-qemu-action@v3 78 | - name: Set up Docker Buildx 79 | uses: docker/setup-buildx-action@v3 80 | - name: Test 81 | uses: devcontainers/ci@v0.2 82 | with: 83 | push: never 84 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 85 | runCmd: | 86 | ./amzn/setup-arm64 87 | ./amzn/test-arm64 88 | ubuntu-py27: 89 | name: Ubuntu x86_64 (Python27) 90 | runs-on: ubuntu-22.04 91 | needs: image 92 | steps: 93 | - name: Checkout 94 | uses: actions/checkout@v4 95 | - name: Test 96 | uses: devcontainers/ci@v0.2 97 | with: 98 | push: never 99 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 100 | runCmd: | 101 | ./py27/setup 102 | ./py27/test 103 | amazonlinux2023-x86-64: 104 | name: AmazonLinux2023/x86_64 105 | runs-on: ubuntu-22.04 106 | needs: image 107 | steps: 108 | - name: Checkout 109 | uses: actions/checkout@v4 110 | - name: Test 111 | uses: devcontainers/ci@v0.2 112 | with: 113 | push: never 114 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 115 | runCmd: | 116 | ./amzn2023/setup 117 | ./amzn2023/test 118 | amazonlinux2023-arm64: 119 | name: AmazonLinux2023 arm64 120 | runs-on: ubuntu-22.04 121 | needs: image 122 | steps: 123 | - name: Checkout 124 | uses: actions/checkout@v4 125 | - name: Set up QEMU 126 | uses: docker/setup-qemu-action@v3 127 | - name: Set up Docker Buildx 128 | uses: docker/setup-buildx-action@v3 129 | - name: Test 130 | uses: devcontainers/ci@v0.2 131 | with: 132 | push: never 133 | cacheFrom: ghcr.io/rails-lambda/crypteia-ci 134 | runCmd: | 135 | ./amzn2023/setup-arm64 136 | ./amzn2023/test-arm64 137 | -------------------------------------------------------------------------------- /test/assert.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | # assert.sh 1.1 - bash unit testing framework 3 | # Copyright (C) 2009-2015 Robert Lehmann 4 | # 5 | # http://github.com/lehmannro/assert.sh 6 | # 7 | # This program is free software: you can redistribute it and/or modify 8 | # it under the terms of the GNU Lesser General Public License as published 9 | # by the Free Software Foundation, either version 3 of the License, or 10 | # (at your option) any later version. 11 | # 12 | # This program is distributed in the hope that it will be useful, 13 | # but WITHOUT ANY WARRANTY; without even the implied warranty of 14 | # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 15 | # GNU Lesser General Public License for more details. 16 | # 17 | # You should have received a copy of the GNU Lesser General Public License 18 | # along with this program. If not, see . 19 | 20 | export DISCOVERONLY=${DISCOVERONLY:-} 21 | export DEBUG=${DEBUG:-} 22 | export STOP=${STOP:-} 23 | export INVARIANT=${INVARIANT:-} 24 | export CONTINUE=${CONTINUE:-} 25 | 26 | args="$(getopt -n "$0" -l \ 27 | verbose,help,stop,discover,invariant,continue vhxdic $*)" \ 28 | || exit -1 29 | for arg in $args; do 30 | case "$arg" in 31 | -h) 32 | echo "$0 [-vxidc]" \ 33 | "[--verbose] [--stop] [--invariant] [--discover] [--continue]" 34 | echo "`sed 's/./ /g' <<< "$0"` [-h] [--help]" 35 | exit 0;; 36 | --help) 37 | cat < [stdin] 103 | (( tests_ran++ )) || : 104 | [[ -z "$DISCOVERONLY" ]] || return 105 | expected=$(echo -ne "${2:-}") 106 | result="$(eval 2>/dev/null $1 <<< ${3:-})" || true 107 | if [[ "$result" == "$expected" ]]; then 108 | [[ -z "$DEBUG" ]] || echo -n . 109 | return 110 | fi 111 | result="$(sed -e :a -e '$!N;s/\n/\\n/;ta' <<< "$result")" 112 | [[ -z "$result" ]] && result="nothing" || result="\"$result\"" 113 | [[ -z "$2" ]] && expected="nothing" || expected="\"$2\"" 114 | _assert_fail "expected $expected${_indent}got $result" "$1" "$3" 115 | } 116 | 117 | assert_raises() { 118 | # assert_raises [stdin] 119 | (( tests_ran++ )) || : 120 | [[ -z "$DISCOVERONLY" ]] || return 121 | status=0 122 | (eval $1 <<< ${3:-}) > /dev/null 2>&1 || status=$? 123 | expected=${2:-0} 124 | if [[ "$status" -eq "$expected" ]]; then 125 | [[ -z "$DEBUG" ]] || echo -n . 126 | return 127 | fi 128 | _assert_fail "program terminated with code $status instead of $expected" "$1" "$3" 129 | } 130 | 131 | _assert_fail() { 132 | # _assert_fail 133 | [[ -n "$DEBUG" ]] && echo -n X 134 | report="test #$tests_ran \"$2${3:+ <<< $3}\" failed:${_indent}$1" 135 | if [[ -n "$STOP" ]]; then 136 | [[ -n "$DEBUG" ]] && echo 137 | echo "$report" 138 | exit 1 139 | fi 140 | tests_errors[$tests_failed]="$report" 141 | (( tests_failed++ )) || : 142 | } 143 | 144 | skip_if() { 145 | # skip_if 146 | (eval $@) > /dev/null 2>&1 && status=0 || status=$? 147 | [[ "$status" -eq 0 ]] || return 148 | skip 149 | } 150 | 151 | skip() { 152 | # skip (no arguments) 153 | shopt -q extdebug && tests_extdebug=0 || tests_extdebug=1 154 | shopt -q -o errexit && tests_errexit=0 || tests_errexit=1 155 | # enable extdebug so returning 1 in a DEBUG trap handler skips next command 156 | shopt -s extdebug 157 | # disable errexit (set -e) so we can safely return 1 without causing exit 158 | set +o errexit 159 | tests_trapped=0 160 | trap _skip DEBUG 161 | } 162 | _skip() { 163 | if [[ $tests_trapped -eq 0 ]]; then 164 | # DEBUG trap for command we want to skip. Do not remove the handler 165 | # yet because *after* the command we need to reset extdebug/errexit (in 166 | # another DEBUG trap.) 167 | tests_trapped=1 168 | [[ -z "$DEBUG" ]] || echo -n s 169 | return 1 170 | else 171 | trap - DEBUG 172 | [[ $tests_extdebug -eq 0 ]] || shopt -u extdebug 173 | [[ $tests_errexit -eq 1 ]] || set -o errexit 174 | return 0 175 | fi 176 | } 177 | 178 | 179 | _assert_reset 180 | : ${tests_suite_status:=0} # remember if any of the tests failed so far 181 | _assert_cleanup() { 182 | local status=$? 183 | # modify exit code if it's not already non-zero 184 | [[ $status -eq 0 && -z $CONTINUE ]] && exit $tests_suite_status 185 | } 186 | trap _assert_cleanup EXIT 187 | -------------------------------------------------------------------------------- /src/ssm.rs: -------------------------------------------------------------------------------- 1 | use crate::log; 2 | use anyhow::Result; 3 | use futures::future::join_all; 4 | use std::collections::HashMap; 5 | use tokio::{spawn, task::JoinHandle}; 6 | use aws_sdk_ssm::config::BehaviorVersion; 7 | 8 | pub async fn get_envs(env_vars: HashMap) -> Result> { 9 | let sdk_config = aws_config::load_defaults(BehaviorVersion::v2024_03_28()).await; 10 | let ssm_client: aws_sdk_ssm::Client = aws_sdk_ssm::Client::new(&sdk_config); 11 | let mut results: HashMap = HashMap::new(); 12 | let mut handles: Vec>>> = Vec::new(); 13 | for (name, path) in env_vars { 14 | if path.starts_with("x-crypteia-ssm:") { 15 | let ssm_clone = ssm_client.clone(); 16 | handles.push(spawn(async move { 17 | ssm_get_parameter(&ssm_clone, name, path).await 18 | })); 19 | } else if path.starts_with("x-crypteia-ssm-path:") { 20 | let ssm_clone = ssm_client.clone(); 21 | handles.push(spawn(async move { 22 | ssm_get_parameters_by_path(&ssm_clone, name, path).await 23 | })); 24 | } 25 | } 26 | let tasks = join_all(handles).await; 27 | for task in tasks { 28 | match task { 29 | Ok(result) => match result { 30 | Ok(parameter) => { 31 | parameter.into_iter().for_each(|(key, value)| { 32 | results.insert(key, value); 33 | }); 34 | } 35 | Err(error) => log::cloudwatch_metric("ssm", "error", true, Some(error.to_string())), 36 | }, 37 | Err(error) => log::cloudwatch_metric("ssm", "error", true, Some(error.to_string())), 38 | } 39 | } 40 | Ok(results) 41 | } 42 | 43 | async fn ssm_get_parameter( 44 | ssm: &aws_sdk_ssm::Client, 45 | name: String, 46 | path: String, 47 | ) -> Result> { 48 | let mut items: HashMap = HashMap::new(); 49 | let response = ssm 50 | .get_parameter() 51 | .name(path.replace("x-crypteia-ssm:", "")) 52 | .with_decryption(true) 53 | .send() 54 | .await; 55 | match response { 56 | Ok(response) => { 57 | if let Some(parameter) = response.parameter { 58 | items.insert(name, parameter.value.unwrap()); 59 | } 60 | } 61 | Err(error) => { 62 | log::cloudwatch_metric( 63 | "ssm", 64 | "error", 65 | true, 66 | Some(format!( 67 | "Error calling ssm:GetParameter. Environment variable: {} Path: {} Error: {:?}", 68 | name, path, error.into_service_error().meta() 69 | )), 70 | ); 71 | } 72 | } 73 | Ok(items) 74 | } 75 | 76 | async fn ssm_get_parameters_by_path( 77 | ssm: &aws_sdk_ssm::Client, 78 | name: String, 79 | path: String, 80 | ) -> Result> { 81 | let mut items: HashMap = HashMap::new(); 82 | let mut token: Option = None; 83 | loop { 84 | let ssm_path = path.replace("x-crypteia-ssm-path:", ""); 85 | let response = ssm 86 | .get_parameters_by_path() 87 | .path(ssm_path.clone()) 88 | .recursive(true) 89 | .with_decryption(true) 90 | .set_next_token(token.clone()) 91 | .send() 92 | .await; 93 | match response { 94 | Ok(response) => { 95 | if let Some(parameters) = response.parameters { 96 | for parameter in parameters { 97 | let path_prefix = parameter.name.unwrap(); 98 | let ssm_clone = ssm_path.clone(); 99 | let ssm_path_replace = ssm_clone + "/"; 100 | let env_name = path_prefix.replace(ssm_path_replace.as_str(), ""); 101 | items.insert(env_name, parameter.value.unwrap()); 102 | } 103 | } 104 | if response.next_token == None { 105 | break; 106 | } 107 | token = response.next_token; 108 | } 109 | Err(error) => { 110 | log::cloudwatch_metric( 111 | "ssm", 112 | "error", 113 | true, 114 | Some(format!( 115 | "Error calling ssm:GetParametersByPath. Environment variable: {} Path: {} Error: {:?}", 116 | name, path, error.into_service_error().meta() 117 | )), 118 | ); 119 | break; 120 | } 121 | } 122 | } 123 | Ok(items) 124 | } 125 | 126 | 127 | #[cfg(test)] 128 | mod test { 129 | use super::*; 130 | use anyhow::Result; 131 | use aws_sdk_ssm::types::ParameterType; 132 | use std::collections::HashMap; 133 | 134 | #[tokio::test] 135 | async fn should_parse() -> Result<()> { 136 | let sdk_config = aws_config::load_defaults(BehaviorVersion::v2024_03_28()).await; 137 | let ssm_client = aws_sdk_ssm::Client::new(&sdk_config); 138 | ssm_client 139 | .put_parameter() 140 | .name("/crypteia/v5/myapp/SECRET".to_owned()) 141 | .value("1A2B3C4D5E6F".to_owned()) 142 | .r#type(ParameterType::SecureString) 143 | .overwrite(true) 144 | .send() 145 | .await?; 146 | ssm_client 147 | .put_parameter() 148 | .name("/crypteia/v5/myapp/access-key".to_owned()) 149 | .value("G7H8I9J0K1L2".to_owned()) 150 | .r#type(ParameterType::SecureString) 151 | .overwrite(true) 152 | .send() 153 | .await?; 154 | ssm_client 155 | .put_parameter() 156 | .name("/crypteia/v5/myapp/envs/DB_URL".to_owned()) 157 | .value("mysql2://u:p@host:3306".to_owned()) 158 | .r#type(ParameterType::SecureString) 159 | .overwrite(true) 160 | .send() 161 | .await?; 162 | ssm_client 163 | .put_parameter() 164 | .name("/crypteia/v5/myapp/envs/NR_KEY".to_owned()) 165 | .value("z6y5x4w3v2u1".to_owned()) 166 | .r#type(ParameterType::SecureString) 167 | .overwrite(true) 168 | .send() 169 | .await?; 170 | let env_vars: HashMap = HashMap::from([ 171 | ("EXISTING".to_string(), "existingvalue".to_string()), 172 | ( 173 | "SECRET".to_string(), 174 | "x-crypteia-ssm:/crypteia/v5/myapp/SECRET".to_string(), 175 | ), 176 | ( 177 | "ACCESS_KEY".to_string(), 178 | "x-crypteia-ssm:/crypteia/v5/myapp/access-key".to_string(), 179 | ), 180 | ( 181 | "X_CRYPTEIA_SSM".to_string(), 182 | "x-crypteia-ssm-path:/crypteia/v5/myapp/envs".to_string(), 183 | ), 184 | ("DB_URL".to_string(), "x-crypteia".to_string()), 185 | ("NR_KEY".to_string(), "x-crypteia".to_string()), 186 | ]); 187 | let expected: HashMap = HashMap::from([ 188 | ("SECRET".to_string(), "1A2B3C4D5E6F".to_string()), 189 | ("ACCESS_KEY".to_string(), "G7H8I9J0K1L2".to_string()), 190 | ("DB_URL".to_string(), "mysql2://u:p@host:3306".to_string()), 191 | ("NR_KEY".to_string(), "z6y5x4w3v2u1".to_string()), 192 | ]); 193 | let results = get_envs(env_vars).await.expect("Should fetch parameters"); 194 | assert_eq!(results, expected); 195 | Ok(()) 196 | } 197 | } -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | [![Actions Status](https://github.com/rails-lambda/crypteia/actions/workflows/test.yml/badge.svg)](https://github.com/rails-lambda/crypteia/actions/workflows/test.yml) 2 | 3 | # 🛡 Crypteia 4 | 5 | ![Node](https://shields.io/badge/x-Node.js-x?logo=node.js&style=plastic&color=339933&label=&labelColor=white) ![Ruby](https://shields.io/badge/x-Ruby-x?logo=ruby&style=plastic&color=CC342D&label=&labelColor=white&logoColor=CC342D) ![PHP](https://shields.io/badge/x-PHP-x?logo=php&style=plastic&color=777BB4&label=&labelColor=white) ![Python](https://shields.io/badge/x-Python-x?logo=python&style=plastic&color=3776AB&label=&labelColor=white) 6 | 7 | ## Rust Lambda Extension for any Runtime to preload SSM Parameters as Secure Environment Variables! 8 | 9 | Super fast and only performed once during your function's initialization, Crypteia turns your serverless YAML from this: 10 | 11 | ```yaml 12 | Environment: 13 | Variables: 14 | SECRET: x-crypteia-ssm:/myapp/SECRET 15 | ``` 16 | 17 | ... into real runtime (no matter the lang) environment variables backed by SSM Parameter Store. For example, assuming the SSM Parameter path above returns `1A2B3C4D5E6F` as the value, your code would return: 18 | 19 | ```javascript 20 | // node 21 | process.env.SECRET; // 1A2B3C4D5E6F 22 | ``` 23 | 24 | ```ruby 25 | # ruby 26 | ENV['SECRET'] # 1A2B3C4D5E6F 27 | ``` 28 | 29 | We do this using our shared object library via the `LD_PRELOAD` environment variable in coordination with our [Lambda Extension](https://docs.aws.amazon.com/lambda/latest/dg/runtimes-extensions-api.html) binary file. Unlike other [AWS SSM Lambda Extension Solutions](https://aws.amazon.com/about-aws/whats-new/2022/10/aws-parameters-secrets-lambda-extension/) your code never needs to know where these environment variables come from. See the [Installation](#installation) and [Usage](#usage) sections for more details. 30 | 31 | 💕 Many thanks to the following projects and people for their work, code, and personal help that made Crypteia possible: 32 | 33 | - **[Hunter Madison](https://github.com/hmadison)**, who taught me about how to use [redhook](https://github.com/geofft/redhook) based on Michele Mancioppi's [opentelemetry-injector](https://github.com/mmanciop/opentelemetry-injector) project. 34 | - **[Jake Scott](https://github.com/jakejscott)** and his [rust-parameters-lambda-extension](https://github.com/jakejscott/rust-parameters-lambda-extension) project which served as the starting point for this project. 35 | 36 | ## Architecture 37 | 38 | There are two main parts for Crypteia, the `crypteia` binary and `libcrypteia.so` shared object file. The following sequence diagram should help highlight how this works with an image's `ENTRYPOINT` and `CMD` interface. 39 | 40 | ```mermaid 41 | sequenceDiagram 42 | actor WRK as Container Workload 43 | participant ENT as 🚪 ENTRYPOINT 44 | participant BIN as 🗑 (bin) crypteia 45 | participant LIB as 📚 (lib) libcrypteia.so 46 | participant CMD as 📢 CMD 47 | participant AWS as 🔒 Secrets Storage 48 | WRK->>ENT: Run 49 | activate ENT 50 | ENT->>BIN: Lambda RIC or ENTRYPOINT 51 | activate BIN 52 | BIN->>AWS: Batch Fetch 53 | AWS->>BIN: Batch Response 54 | BIN->>BIN: crypteia.json (write) 55 | BIN->>WRK: 56 | deactivate BIN 57 | deactivate ENT 58 | WRK->>CMD: Run 59 | activate CMD 60 | CMD->>LIB: LD_PRELOAD 61 | activate LIB 62 | LIB->>LIB: crypteia.json (read/delete) 63 | LIB->>CMD: 🔐 Shared Memory 64 | deactivate LIB 65 | CMD->>CMD: getenv(3) 66 | CMD->>WRK: 67 | deactivate CMD 68 | ``` 69 | 70 | Secrets are fetched in batch via the `ENTRYPOINT`. This is done for you automatically with the Lambda Runtime Interface Client as part of the Lambda Extensions interface. When using Ctypteia with other container tools, calling the binary `/opt/extensions/crypteia` would need to be done as an explicit `ENTRYPOINT` or part of that script. When your `CMD` process is running, replacing `x-crypteia` prefixed environment values with `getenv(3)` is done quickly in memory. 71 | 72 | ## Installation 73 | 74 | When building your own Lambda Containers, use both the `crypteia` binary and `libcrypteia.so` shared object files that match your platform. Target platform naming conventions include the following: 75 | 76 | - Amazon Linux 2: uses the `-amzn` suffix. 77 | - Debian, Ubuntu, etc.: uses the `-debian` suffix. 78 | 79 | > **Note** 80 | > 🦾 All of our images are multi-platform supporting both `amd64` and `arm64` for linux. We use Docker manifests and there is no need to use special tags. 81 | 82 | #### Lambda Containers 83 | 84 | There are two options for Lambda containers. The easiest is to use Docker's multi stage builds with our [Extension Containers]([https://github.com/orgs/rails-lambda/packages?ecosystem=container&tab=packages&ecosystem=container&q=extension](https://github.com/orgs/rails-lambda/packages?repo_name=crypteia&q=extension)) to copy the `/opt` directory matching your platform and Crypteia version number. example below. Remember to use `-debian` vs `-amzn` if you are using your own Linux containers. Or change the version number depending on your needs. 85 | 86 | ```dockerfile 87 | FROM ghcr.io/rails-lambda/crypteia-extension-amzn:1 AS crypteia 88 | FROM public.ecr.aws/lambda/nodejs:18 89 | COPY --from=crypteia /opt /opt 90 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 91 | ``` 92 | 93 | Alternatively, you can download your platform's binary and shared object file from our [Releases](https://github.com/rails-lambda/crypteia/releases) page and place them into your projects Docker build directory. Remember to remove the platform file suffix. Example: 94 | 95 | ```dockerfile 96 | RUN mkdir -p /opt/lib 97 | RUN mkdir -p /opt/extensions 98 | COPY crypteia /opt/extensions/crypteia 99 | COPY libcrypteia.so /opt/lib/libcrypteia.so 100 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 101 | ``` 102 | 103 | If you are using Python you will need to add our Crypteia python package to the `PYTHONPATH` in order for things to "just work". The result of this will be that `os.environ["SECRET"]`, `os.environ.get("SECRET")`, and `os.getenv("SECRET")` will be routed to the `getenv` system call and therefore take advantage of the Crypteia rust extension. 104 | 105 | ```dockerfile 106 | ENV PYTHONPATH=/opt/crypteia/python 107 | ``` 108 | 109 | > **Warning** 110 | > When building your own Lambda Containers, please make sure [glibc](https://www.gnu.org/software/libc/) is installed since this is used by [redhook](https://github.com/geofft/redhook). 111 | 112 | #### Lambda Extension 113 | 114 | Our Amazon Linux 2 files can be used within a [Lambda Extension](https://docs.aws.amazon.com/lambda/latest/dg/using-extensions.html) that you can deploy to your own AWS account as a [Lambda Layer](https://docs.aws.amazon.com/lambda/latest/dg/configuration-layers.html). You can use this project to build, publish, and deploy that layer since it has the SAM CLI installed. All you need to do is supply your own S3 bucket. The process differ slightly for `arm64`, but for both, open up the [development container](#development) and start off by configuring the AWS CLI to access the account needed. 115 | 116 | ```shell 117 | aws configure 118 | ``` 119 | 120 | The `package/template.yml` file has a the layer's [CompatibleArchitectures](https://docs.aws.amazon.com/AWSCloudFormation/latest/UserGuide/aws-resource-lambda-layerversion.html) set to `x86_64`. So these commands work without changes. 121 | 122 | ```shell 123 | ./amzn/setup 124 | S3_BUCKET_NAME=my-bucket ./package/deploy 125 | ``` 126 | 127 | However, for `arm64` the process would be a little different. First open the `package/template.yml` and change the `CompatibleArchitectures` value from `x86_64` to `arm64`. Now run the following commands to publish the lambda layer. Optionally, if you want to create distinct layer names for each arch, feel free open up the `package/deploy` file and change the `--stack-name` as you see fit. 128 | 129 | ```shell 130 | ./amzn/setup-arm64 131 | S3_BUCKET_NAME=my-bucket ./package/deploy 132 | ``` 133 | 134 | #### Other Containers 135 | 136 | If you are using Crypteia on your own Docker containers without the Lambda Extension mechanics, you can simply set the `ENTRYPOINT` to the Crypteia binary which fetches your environment variables so the shared object preload can use them. 137 | 138 | ```dockerfile 139 | FROM ghcr.io/rails-lambda/crypteia-extension-amzn:1 AS crypteia 140 | FROM ubuntu 141 | COPY --from=crypteia /opt /opt 142 | ENV LD_PRELOAD=/opt/lib/libcrypteia.so 143 | ENTRYPOINT /opt/extensions/crypteia 144 | ``` 145 | 146 | ## Usage 147 | 148 | First, you will need your secret environment variables setup in [AWS Systems Manager Parameter Store](https://docs.aws.amazon.com/systems-manager/latest/userguide/systems-manager-parameter-store.html). These can be whatever [hierarchy](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-hierarchies.html) you choose. Parameters can be any string type. However, we recommend using `SecureString` to ensure your secrets are encrypted within AWS. For example, let's assume the following paramter paths and values exist: 149 | 150 | - `/myapp/SECRET` -> `1A2B3C4D5E6F` 151 | - `/myapp/access-key` -> `G7H8I9J0K1L2` 152 | - `/myapp/envs/DB_URL` -> `mysql2://u:p@host:3306` 153 | - `/myapp/envs/NR_KEY` -> `z6y5x4w3v2u1` 154 | 155 | Crypteia supports two methods to fetch SSM parameters: 156 | 157 | 1. `x-crypteia-ssm:` - [Single] path for a single environment variable. 158 | 2. `x-crypteia-ssm-path:` - [Group] Path prefix to fetch many environment variables. 159 | 160 | Using whatever serverless framework you prefer, and set up your function's environment variables using either of the two SSM interfaces from above. For example, here is an environment variables section for an [AWS SAM](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-getting-started.html) template that demonstrates all of Crypteia's features. 161 | 162 | ```yaml 163 | Environment: 164 | Variables: 165 | # [Single] Example 166 | SECRET: x-crypteia-ssm:/myapp/SECRET 167 | ACCESS_KEY: x-crypteia-ssm:/myapp/access-key 168 | # [Group] Example 169 | X_CRYPTEIA_SSM: x-crypteia-ssm-path:/myapp/envs 170 | DB_URL: x-crypteia 171 | NR_KEY: x-crypteia 172 | ``` 173 | 174 | When your function initializes, each of the four environmet variables (`SECRET`, `ACCESS_KEY`, `DB_URL`, and `NR_KEY`) will return values from their respective SSM paths. 175 | 176 | ```javascript 177 | // node 178 | process.env.SECRET; // 1A2B3C4D5E6F 179 | process.env.ACCESS_KEY; // G7H8I9J0K1L2 180 | process.env.DB_URL; // mysql2://u:p@host:3306 181 | process.env.NR_KEY; // z6y5x4w3v2u1 182 | ``` 183 | 184 | ```ruby 185 | # ruby 186 | env["SECRET"]; ## 1A2B3C4D5E6F 187 | env["ACCESS_KEY"]; ## G7H8I9J0K1L2 188 | env["DB_URL"]; ## mysql2://u:p@host:3306 189 | env["NR_KEY"]; ## z6y5x4w3v2u1 190 | ``` 191 | 192 | Here are a few details about how Crypteia works with respect to the internal implementation: 193 | 194 | 1. When accessing a single parameter path via `x-crypteia-ssm:`, the environment variable name available to your runtime is used as is. No part of the parameter path influences the resulting name. 195 | 2. When using `x-crypteia-ssm-path:`, the environment variable name can be anything and the value is left unchanged. 196 | 3. The parameter path hierarchy passed with `x-crypteia-ssm-path:` must be one level deep and end with valid environment variable names. These names must match environement placeholders using `x-crypteia` values. 197 | 198 | For security, the usage of `DB_URL: x-crypteia` placeholders ensures that your application's configuration is in full control of which dynamic values can be used with `x-crypteia-ssm-path:`. 199 | 200 | Shown below is a simple Node.js 16 function which has the appropriate [IAM Permissions](#iam-permissions) and Crypteia extension via an installed Lambda Layer. Also configured are the necessary `LD_PRELOAD` and `SECRET` environment variables. The code in this function logs the value of the `process.env.SECRET` which correctly resolves to the value from SSM Parameter Store. 201 | 202 | ![Screenshot of the Environment variables in the AWS Lambda Console showing `LD_PRELOAD` to `/opt/lib/libcrypteia.so` and `SECRET` to `x-crypteia-ssm:/myapp/SECRET`.](/images/readme-env-variables.png) 203 | 204 | ![Screenshot of Code source in the AWS Lambda Console showing the `body` results of `1A2B3C4D5E6F` which is resolved from SSM Parameter Store.](/images/readme-code-results.png) 205 | 206 | #### Using Dynamic SSM Paths 207 | 208 | Your `template.yaml` file can contain input `Parameters` that indicates the environment of the app. You can use this parameter to fetch the correct env variable in SSM depending on the environment you are deploying your app to. For exemple, a [Lamby app](https://lamby.cloud/docs/quick-start) has a `RailsEnv` parameter which is commonly set to to indicate the environment you running under: 209 | 210 | ```yaml 211 | Parameters: 212 | RailsEnv: 213 | Type: String 214 | Default: staging 215 | AllowedValues: 216 | - staging 217 | - production 218 | ``` 219 | 220 | This parameter can be used to fetch SSM-backed environment variables that leveage dynamic paths like `/myapp/${RailsEnv}/MY_VARIABLE`. The `template.yaml` file will then look like this example below. This way you can have one different SSM variable for each one of your environments in a single AWS account. 221 | 222 | ```yaml 223 | Environment: 224 | Variables: 225 | SECRET: x-crypteia-ssm:/myapp/${RailsEnv}/SECRET 226 | ACCESS_KEY: x-crypteia-ssm:/myapp/${RailsEnv}/access-key 227 | X_CRYPTEIA_SSM: x-crypteia-ssm-path:/myapp/${RailsEnv}/envs 228 | ``` 229 | 230 | #### IAM Permissions 231 | 232 | Please refer to the AWS guide on [Restricting access to Systems Manager parameters using IAM policies](https://docs.aws.amazon.com/systems-manager/latest/userguide/sysman-paramstore-access.html) for details on which policies your function's IAM Role will need. These examples assume the `/myapp` prefix and should work for direct secrets in that path or further nesting in a path prefix as described in the [usage section](#usage). 233 | 234 | ```json 235 | { 236 | "Version": "2012-10-17", 237 | "Statement": [ 238 | { 239 | "Effect": "Allow", 240 | "Action": ["ssm:Get*", "ssm:Describe*"], 241 | "Resource": "arn:aws:ssm:*:${AWS::AccountId}:parameter/myapp/*" 242 | } 243 | ] 244 | } 245 | ``` 246 | 247 | Here is an example [Policies](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/sam-resource-function.html#sam-function-policies) section you could add to your AWS SAM `template.yaml` file. 248 | 249 | ```yaml 250 | Policies: 251 | - Statement: 252 | - Effect: Allow 253 | Action: ["ssm:Get*", "ssm:Describe*"] 254 | Resource: 255 | - !Sub arn:aws:ssm:*:${AWS::AccountId}:parameter/myapp/* 256 | ``` 257 | 258 | > **Note** 259 | > If you are not using the default encryption key, you will also need to add a [KMSDecryptPolicy](https://docs.aws.amazon.com/serverless-application-model/latest/developerguide/serverless-policy-template-list.html#kms-decrypt-policy) policy. 260 | 261 | 262 | #### Troubleshooting 263 | 264 | Crypteia has very verbose logging which is enabled via the `CRYPTEIA_DEBUG` environment variable: 265 | 266 | ```ruby 267 | CRYPTEIA_DEBUG: true 268 | ``` 269 | 270 | Example of logs: 271 | 272 | ```log 273 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","lib"]],"Metrics":[{"Name":"initialized","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424178585},"initialized":1,"lib":"lib"} 274 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","main"]],"Metrics":[{"Name":"initialized","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424178590},"initialized":1,"main":"main"} 275 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","main"]],"Metrics":[{"Name":"fetched","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424178831},"fetched":1,"main":"main"} 276 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","lib"]],"Metrics":[{"Name":"initialized","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424178892},"initialized":1,"lib":"lib"} 277 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","lib"]],"Metrics":[{"Name":"is_env_file","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424179575},"is_env_file":1,"lib":"lib"} 278 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","lib"]],"Metrics":[{"Name":"read_env_file","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424179575},"lib":"lib","read_env_file":1} 279 | {"All":"all","ErrorMessage":"","_aws":{"CloudWatchMetrics":[{"Dimensions":[["All","lib"]],"Metrics":[{"Name":"delete_file","Unit":"Count"}],"Namespace":"Crypteia"}],"Timestamp":1670424179575},"delete_file":1,"lib":"lib"} 280 | ``` 281 | 282 | If you are using a slim image such as bookworm slim or alpine, you might have missing dependencies. Recent [issue report](https://github.com/rails-lambda/crypteia/issues/51#issuecomment-2739322306) suggests the following addition to your image may help: 283 | 284 | ```docerfile 285 | RUN apt-get update && apt-get install -y --no-install-recommends \ 286 | ca-certificates \ 287 | && update-ca-certificates \ 288 | && rm -rf /var/lib/apt/lists/* 289 | ``` 290 | 291 | ## Development 292 | 293 | This project is built for [GitHub Codespcaes](https://github.com/features/codespaces) using the [Development Container](https://containers.dev) specification. Even though Codespaces may not be available to everyone, this project's containers are simple for anyone to make work with any editor. 294 | 295 | Our development container is based on the [vscode-remote-try-rust](https://github.com/microsoft/vscode-remote-try-rust) demo project. For details on the VS Code Rust development container, have a look at the [container's history](https://github.com/microsoft/vscode-dev-containers/tree/main/containers/rust/history). Once you have the repo cloned and set up with a dev container using Codespaces, [VS Code](#using-vs-code), or the [Dev Container CLI](#dev-container-cli), run the following commands which will install packages, build your project, and run tests without needing to connect to SSM: 296 | 297 | 298 | ```shell 299 | ./bin/setup 300 | ./bin/test-local 301 | ``` 302 | 303 | If you want to test SSM with your AWS account, the AWS CLI is installed on the dev container. Set it up with your **test credentials** using the following. These will be passed thru to various build/test containers. 304 | 305 | ```shell 306 | export AWS_ACCESS_KEY_ID=... 307 | export AWS_SECRET_ACCESS_KEY=... 308 | export AWS_REGION=... 309 | ``` 310 | 311 | You can also develop using the Amazon Linux 2 support. This will use Docker-in-Docker to download AWS SAM and Lambda images to build cryptia using what is present (e.g. glibc) in your environment: 312 | 313 | ```shell 314 | ./amzn/setup 315 | ./amzn/test 316 | ``` 317 | 318 | #### Using VS Code 319 | 320 | If you have the [Visual Studio Code Dev Container](https://marketplace.visualstudio.com/items?itemName=ms-vscode-remote.remote-containers) extension installed you can easily clone this repository locally, use the "Open Folder in Container..." command, and use the integrated terminal for your setup and test commands. Example: 321 | 322 | ![VS Code showing the "Dev Containers: Open Folder in Container..." command.](/images/readme-devcontainer-open-folder.png) 323 | 324 | ![VS Code window with the Crypteia project open in a dev container. Shown too are the tests running.](/images/readme-devcontainer-vscode.png) 325 | 326 | #### Dev Container CLI 327 | 328 | You can use the open-source [Dev Container CLI](https://github.com/devcontainers/cli) to mimic what Codespaces and/or VS Code are doing for you. In this way, you can use different editors. You must have Docker installed. Here are the commands to build the dev container and setup/test the project: 329 | 330 | ```shell 331 | devcontainer build --workspace-folder . 332 | devcontainer up --workspace-folder . 333 | devcontainer run-user-commands --workspace-folder . 334 | ``` 335 | 336 | ```shell 337 | devcontainer exec --workspace-folder . ./bin/setup 338 | devcontainer exec --workspace-folder . ./bin/test-local 339 | ``` 340 | 341 | ![Showing Sublime Text on a Mac using the Dev Container CLI to run Crypteia tests.](/images/readme-devcontainer-cli-sublime.png) 342 | -------------------------------------------------------------------------------- /Cargo.lock: -------------------------------------------------------------------------------- 1 | # This file is automatically @generated by Cargo. 2 | # It is not intended for manual editing. 3 | version = 3 4 | 5 | [[package]] 6 | name = "addr2line" 7 | version = "0.22.0" 8 | source = "registry+https://github.com/rust-lang/crates.io-index" 9 | checksum = "6e4503c46a5c0c7844e948c9a4d6acd9f50cccb4de1c48eb9e291ea17470c678" 10 | dependencies = [ 11 | "gimli", 12 | ] 13 | 14 | [[package]] 15 | name = "adler" 16 | version = "1.0.2" 17 | source = "registry+https://github.com/rust-lang/crates.io-index" 18 | checksum = "f26201604c87b1e01bd3d98f8d5d9a8fcbb815e8cedb41ffccbeb4bf593a35fe" 19 | 20 | [[package]] 21 | name = "android_system_properties" 22 | version = "0.1.5" 23 | source = "registry+https://github.com/rust-lang/crates.io-index" 24 | checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" 25 | dependencies = [ 26 | "libc", 27 | ] 28 | 29 | [[package]] 30 | name = "anyhow" 31 | version = "1.0.86" 32 | source = "registry+https://github.com/rust-lang/crates.io-index" 33 | checksum = "b3d1d046238990b9cf5bcde22a3fb3584ee5cf65fb2765f454ed428c7a0063da" 34 | 35 | [[package]] 36 | name = "async-stream" 37 | version = "0.3.3" 38 | source = "registry+https://github.com/rust-lang/crates.io-index" 39 | checksum = "dad5c83079eae9969be7fadefe640a1c566901f05ff91ab221de4b6f68d9507e" 40 | dependencies = [ 41 | "async-stream-impl", 42 | "futures-core", 43 | ] 44 | 45 | [[package]] 46 | name = "async-stream-impl" 47 | version = "0.3.3" 48 | source = "registry+https://github.com/rust-lang/crates.io-index" 49 | checksum = "10f203db73a71dfa2fb6dd22763990fa26f3d2625a6da2da900d23b87d26be27" 50 | dependencies = [ 51 | "proc-macro2", 52 | "quote", 53 | "syn 1.0.107", 54 | ] 55 | 56 | [[package]] 57 | name = "autocfg" 58 | version = "1.1.0" 59 | source = "registry+https://github.com/rust-lang/crates.io-index" 60 | checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" 61 | 62 | [[package]] 63 | name = "aws-config" 64 | version = "1.5.1" 65 | source = "registry+https://github.com/rust-lang/crates.io-index" 66 | checksum = "2ac9889352d632214df943e26740c46a0f3da6e329fbd28164fe7ae1b061da7b" 67 | dependencies = [ 68 | "aws-credential-types", 69 | "aws-runtime", 70 | "aws-sdk-sso", 71 | "aws-sdk-ssooidc", 72 | "aws-sdk-sts", 73 | "aws-smithy-async", 74 | "aws-smithy-http", 75 | "aws-smithy-json", 76 | "aws-smithy-runtime", 77 | "aws-smithy-runtime-api", 78 | "aws-smithy-types", 79 | "aws-types", 80 | "bytes", 81 | "fastrand", 82 | "hex", 83 | "http 0.2.12", 84 | "hyper 0.14.29", 85 | "ring 0.17.8", 86 | "time 0.3.17", 87 | "tokio", 88 | "tracing", 89 | "url", 90 | "zeroize", 91 | ] 92 | 93 | [[package]] 94 | name = "aws-credential-types" 95 | version = "1.2.0" 96 | source = "registry+https://github.com/rust-lang/crates.io-index" 97 | checksum = "e16838e6c9e12125face1c1eff1343c75e3ff540de98ff7ebd61874a89bcfeb9" 98 | dependencies = [ 99 | "aws-smithy-async", 100 | "aws-smithy-runtime-api", 101 | "aws-smithy-types", 102 | "zeroize", 103 | ] 104 | 105 | [[package]] 106 | name = "aws-runtime" 107 | version = "1.2.3" 108 | source = "registry+https://github.com/rust-lang/crates.io-index" 109 | checksum = "36978815abdd7297662bf906adff132941a02ecf425bc78fac7d90653ce87560" 110 | dependencies = [ 111 | "aws-credential-types", 112 | "aws-sigv4", 113 | "aws-smithy-async", 114 | "aws-smithy-http", 115 | "aws-smithy-runtime-api", 116 | "aws-smithy-types", 117 | "aws-types", 118 | "bytes", 119 | "fastrand", 120 | "http 0.2.12", 121 | "http-body 0.4.5", 122 | "percent-encoding", 123 | "pin-project-lite", 124 | "tracing", 125 | "uuid", 126 | ] 127 | 128 | [[package]] 129 | name = "aws-sdk-ssm" 130 | version = "1.34.0" 131 | source = "registry+https://github.com/rust-lang/crates.io-index" 132 | checksum = "de30f6bc149f01e3505cf1c62edd9f4a78f1a3f32dd4bc6f2eba9cc44865ab69" 133 | dependencies = [ 134 | "aws-credential-types", 135 | "aws-runtime", 136 | "aws-smithy-async", 137 | "aws-smithy-http", 138 | "aws-smithy-json", 139 | "aws-smithy-runtime", 140 | "aws-smithy-runtime-api", 141 | "aws-smithy-types", 142 | "aws-types", 143 | "bytes", 144 | "fastrand", 145 | "http 0.2.12", 146 | "once_cell", 147 | "regex-lite", 148 | "tracing", 149 | ] 150 | 151 | [[package]] 152 | name = "aws-sdk-sso" 153 | version = "1.31.0" 154 | source = "registry+https://github.com/rust-lang/crates.io-index" 155 | checksum = "7833dd5b061741825b8531360789bbd74fc365674601d3e9a79914310be320f9" 156 | dependencies = [ 157 | "aws-credential-types", 158 | "aws-runtime", 159 | "aws-smithy-async", 160 | "aws-smithy-http", 161 | "aws-smithy-json", 162 | "aws-smithy-runtime", 163 | "aws-smithy-runtime-api", 164 | "aws-smithy-types", 165 | "aws-types", 166 | "bytes", 167 | "http 0.2.12", 168 | "once_cell", 169 | "regex-lite", 170 | "tracing", 171 | ] 172 | 173 | [[package]] 174 | name = "aws-sdk-ssooidc" 175 | version = "1.32.0" 176 | source = "registry+https://github.com/rust-lang/crates.io-index" 177 | checksum = "c531346d4f36874b74ea82978a03011ab413b007b841029a8c30a48f18cc3f37" 178 | dependencies = [ 179 | "aws-credential-types", 180 | "aws-runtime", 181 | "aws-smithy-async", 182 | "aws-smithy-http", 183 | "aws-smithy-json", 184 | "aws-smithy-runtime", 185 | "aws-smithy-runtime-api", 186 | "aws-smithy-types", 187 | "aws-types", 188 | "bytes", 189 | "http 0.2.12", 190 | "once_cell", 191 | "regex-lite", 192 | "tracing", 193 | ] 194 | 195 | [[package]] 196 | name = "aws-sdk-sts" 197 | version = "1.31.0" 198 | source = "registry+https://github.com/rust-lang/crates.io-index" 199 | checksum = "ca214135f34b4841050f6466d4a56743e02aa63169f1b5e77161043f20653400" 200 | dependencies = [ 201 | "aws-credential-types", 202 | "aws-runtime", 203 | "aws-smithy-async", 204 | "aws-smithy-http", 205 | "aws-smithy-json", 206 | "aws-smithy-query", 207 | "aws-smithy-runtime", 208 | "aws-smithy-runtime-api", 209 | "aws-smithy-types", 210 | "aws-smithy-xml", 211 | "aws-types", 212 | "http 0.2.12", 213 | "once_cell", 214 | "regex-lite", 215 | "tracing", 216 | ] 217 | 218 | [[package]] 219 | name = "aws-sigv4" 220 | version = "1.2.2" 221 | source = "registry+https://github.com/rust-lang/crates.io-index" 222 | checksum = "31eed8d45759b2c5fe7fd304dd70739060e9e0de509209036eabea14d0720cce" 223 | dependencies = [ 224 | "aws-credential-types", 225 | "aws-smithy-http", 226 | "aws-smithy-runtime-api", 227 | "aws-smithy-types", 228 | "bytes", 229 | "form_urlencoded", 230 | "hex", 231 | "hmac", 232 | "http 0.2.12", 233 | "http 1.1.0", 234 | "once_cell", 235 | "percent-encoding", 236 | "sha2", 237 | "time 0.3.17", 238 | "tracing", 239 | ] 240 | 241 | [[package]] 242 | name = "aws-smithy-async" 243 | version = "1.2.1" 244 | source = "registry+https://github.com/rust-lang/crates.io-index" 245 | checksum = "62220bc6e97f946ddd51b5f1361f78996e704677afc518a4ff66b7a72ea1378c" 246 | dependencies = [ 247 | "futures-util", 248 | "pin-project-lite", 249 | "tokio", 250 | ] 251 | 252 | [[package]] 253 | name = "aws-smithy-http" 254 | version = "0.60.8" 255 | source = "registry+https://github.com/rust-lang/crates.io-index" 256 | checksum = "4a7de001a1b9a25601016d8057ea16e31a45fdca3751304c8edf4ad72e706c08" 257 | dependencies = [ 258 | "aws-smithy-runtime-api", 259 | "aws-smithy-types", 260 | "bytes", 261 | "bytes-utils", 262 | "futures-core", 263 | "http 0.2.12", 264 | "http-body 0.4.5", 265 | "once_cell", 266 | "percent-encoding", 267 | "pin-project-lite", 268 | "pin-utils", 269 | "tracing", 270 | ] 271 | 272 | [[package]] 273 | name = "aws-smithy-json" 274 | version = "0.60.7" 275 | source = "registry+https://github.com/rust-lang/crates.io-index" 276 | checksum = "4683df9469ef09468dad3473d129960119a0d3593617542b7d52086c8486f2d6" 277 | dependencies = [ 278 | "aws-smithy-types", 279 | ] 280 | 281 | [[package]] 282 | name = "aws-smithy-query" 283 | version = "0.60.7" 284 | source = "registry+https://github.com/rust-lang/crates.io-index" 285 | checksum = "f2fbd61ceb3fe8a1cb7352e42689cec5335833cd9f94103a61e98f9bb61c64bb" 286 | dependencies = [ 287 | "aws-smithy-types", 288 | "urlencoding", 289 | ] 290 | 291 | [[package]] 292 | name = "aws-smithy-runtime" 293 | version = "1.6.0" 294 | source = "registry+https://github.com/rust-lang/crates.io-index" 295 | checksum = "db83b08939838d18e33b5dbaf1a0f048f28c10bd28071ab7ce6f245451855414" 296 | dependencies = [ 297 | "aws-smithy-async", 298 | "aws-smithy-http", 299 | "aws-smithy-runtime-api", 300 | "aws-smithy-types", 301 | "bytes", 302 | "fastrand", 303 | "h2", 304 | "http 0.2.12", 305 | "http-body 0.4.5", 306 | "http-body 1.0.0", 307 | "httparse", 308 | "hyper 0.14.29", 309 | "hyper-rustls", 310 | "once_cell", 311 | "pin-project-lite", 312 | "pin-utils", 313 | "rustls", 314 | "tokio", 315 | "tracing", 316 | ] 317 | 318 | [[package]] 319 | name = "aws-smithy-runtime-api" 320 | version = "1.7.0" 321 | source = "registry+https://github.com/rust-lang/crates.io-index" 322 | checksum = "1b570ea39eb95bd32543f6e4032bce172cb6209b9bc8c83c770d08169e875afc" 323 | dependencies = [ 324 | "aws-smithy-async", 325 | "aws-smithy-types", 326 | "bytes", 327 | "http 0.2.12", 328 | "http 1.1.0", 329 | "pin-project-lite", 330 | "tokio", 331 | "tracing", 332 | "zeroize", 333 | ] 334 | 335 | [[package]] 336 | name = "aws-smithy-types" 337 | version = "1.2.0" 338 | source = "registry+https://github.com/rust-lang/crates.io-index" 339 | checksum = "cfe321a6b21f5d8eabd0ade9c55d3d0335f3c3157fc2b3e87f05f34b539e4df5" 340 | dependencies = [ 341 | "base64-simd", 342 | "bytes", 343 | "bytes-utils", 344 | "futures-core", 345 | "http 0.2.12", 346 | "http 1.1.0", 347 | "http-body 0.4.5", 348 | "http-body 1.0.0", 349 | "http-body-util", 350 | "itoa", 351 | "num-integer", 352 | "pin-project-lite", 353 | "pin-utils", 354 | "ryu", 355 | "serde", 356 | "time 0.3.17", 357 | "tokio", 358 | "tokio-util", 359 | ] 360 | 361 | [[package]] 362 | name = "aws-smithy-xml" 363 | version = "0.60.8" 364 | source = "registry+https://github.com/rust-lang/crates.io-index" 365 | checksum = "d123fbc2a4adc3c301652ba8e149bf4bc1d1725affb9784eb20c953ace06bf55" 366 | dependencies = [ 367 | "xmlparser", 368 | ] 369 | 370 | [[package]] 371 | name = "aws-types" 372 | version = "1.3.1" 373 | source = "registry+https://github.com/rust-lang/crates.io-index" 374 | checksum = "6f734808d43702a67e57d478a12e227d4d038d0b90c9005a78c87890d3805922" 375 | dependencies = [ 376 | "aws-credential-types", 377 | "aws-smithy-async", 378 | "aws-smithy-runtime-api", 379 | "aws-smithy-types", 380 | "http 0.2.12", 381 | "rustc_version", 382 | "tracing", 383 | ] 384 | 385 | [[package]] 386 | name = "backtrace" 387 | version = "0.3.73" 388 | source = "registry+https://github.com/rust-lang/crates.io-index" 389 | checksum = "5cc23269a4f8976d0a4d2e7109211a419fe30e8d88d677cd60b6bc79c5732e0a" 390 | dependencies = [ 391 | "addr2line", 392 | "cc", 393 | "cfg-if", 394 | "libc", 395 | "miniz_oxide", 396 | "object", 397 | "rustc-demangle", 398 | ] 399 | 400 | [[package]] 401 | name = "base64" 402 | version = "0.21.0" 403 | source = "registry+https://github.com/rust-lang/crates.io-index" 404 | checksum = "a4a4ddaa51a5bc52a6948f74c06d20aaaddb71924eab79b8c97a8c556e942d6a" 405 | 406 | [[package]] 407 | name = "base64-simd" 408 | version = "0.8.0" 409 | source = "registry+https://github.com/rust-lang/crates.io-index" 410 | checksum = "339abbe78e73178762e23bea9dfd08e697eb3f3301cd4be981c0f78ba5859195" 411 | dependencies = [ 412 | "outref", 413 | "vsimd", 414 | ] 415 | 416 | [[package]] 417 | name = "bitflags" 418 | version = "1.3.2" 419 | source = "registry+https://github.com/rust-lang/crates.io-index" 420 | checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" 421 | 422 | [[package]] 423 | name = "block-buffer" 424 | version = "0.10.3" 425 | source = "registry+https://github.com/rust-lang/crates.io-index" 426 | checksum = "69cce20737498f97b993470a6e536b8523f0af7892a4f928cceb1ac5e52ebe7e" 427 | dependencies = [ 428 | "generic-array", 429 | ] 430 | 431 | [[package]] 432 | name = "bumpalo" 433 | version = "3.12.0" 434 | source = "registry+https://github.com/rust-lang/crates.io-index" 435 | checksum = "0d261e256854913907f67ed06efbc3338dfe6179796deefc1ff763fc1aee5535" 436 | 437 | [[package]] 438 | name = "bytes" 439 | version = "1.6.0" 440 | source = "registry+https://github.com/rust-lang/crates.io-index" 441 | checksum = "514de17de45fdb8dc022b1a7975556c53c86f9f0aa5f534b98977b171857c2c9" 442 | 443 | [[package]] 444 | name = "bytes-utils" 445 | version = "0.1.3" 446 | source = "registry+https://github.com/rust-lang/crates.io-index" 447 | checksum = "e47d3a8076e283f3acd27400535992edb3ba4b5bb72f8891ad8fbe7932a7d4b9" 448 | dependencies = [ 449 | "bytes", 450 | "either", 451 | ] 452 | 453 | [[package]] 454 | name = "cc" 455 | version = "1.0.99" 456 | source = "registry+https://github.com/rust-lang/crates.io-index" 457 | checksum = "96c51067fd44124faa7f870b4b1c969379ad32b2ba805aa959430ceaa384f695" 458 | 459 | [[package]] 460 | name = "cfg-if" 461 | version = "1.0.0" 462 | source = "registry+https://github.com/rust-lang/crates.io-index" 463 | checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" 464 | 465 | [[package]] 466 | name = "chrono" 467 | version = "0.4.23" 468 | source = "registry+https://github.com/rust-lang/crates.io-index" 469 | checksum = "16b0a3d9ed01224b22057780a37bb8c5dbfe1be8ba48678e7bf57ec4b385411f" 470 | dependencies = [ 471 | "iana-time-zone", 472 | "js-sys", 473 | "num-integer", 474 | "num-traits", 475 | "serde", 476 | "time 0.1.45", 477 | "wasm-bindgen", 478 | "winapi", 479 | ] 480 | 481 | [[package]] 482 | name = "codespan-reporting" 483 | version = "0.11.1" 484 | source = "registry+https://github.com/rust-lang/crates.io-index" 485 | checksum = "3538270d33cc669650c4b093848450d380def10c331d38c768e34cac80576e6e" 486 | dependencies = [ 487 | "termcolor", 488 | "unicode-width", 489 | ] 490 | 491 | [[package]] 492 | name = "core-foundation" 493 | version = "0.9.3" 494 | source = "registry+https://github.com/rust-lang/crates.io-index" 495 | checksum = "194a7a9e6de53fa55116934067c844d9d749312f75c6f6d0980e8c252f8c2146" 496 | dependencies = [ 497 | "core-foundation-sys", 498 | "libc", 499 | ] 500 | 501 | [[package]] 502 | name = "core-foundation-sys" 503 | version = "0.8.3" 504 | source = "registry+https://github.com/rust-lang/crates.io-index" 505 | checksum = "5827cebf4670468b8772dd191856768aedcb1b0278a04f989f7766351917b9dc" 506 | 507 | [[package]] 508 | name = "cpufeatures" 509 | version = "0.2.5" 510 | source = "registry+https://github.com/rust-lang/crates.io-index" 511 | checksum = "28d997bd5e24a5928dd43e46dc529867e207907fe0b239c3477d924f7f2ca320" 512 | dependencies = [ 513 | "libc", 514 | ] 515 | 516 | [[package]] 517 | name = "crypteia" 518 | version = "2.0.0" 519 | dependencies = [ 520 | "anyhow", 521 | "aws-config", 522 | "aws-sdk-ssm", 523 | "futures", 524 | "lambda-extension", 525 | "lazy_static", 526 | "libc", 527 | "redhook", 528 | "serde_json", 529 | "tokio", 530 | ] 531 | 532 | [[package]] 533 | name = "crypto-common" 534 | version = "0.1.6" 535 | source = "registry+https://github.com/rust-lang/crates.io-index" 536 | checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" 537 | dependencies = [ 538 | "generic-array", 539 | "typenum", 540 | ] 541 | 542 | [[package]] 543 | name = "cxx" 544 | version = "1.0.86" 545 | source = "registry+https://github.com/rust-lang/crates.io-index" 546 | checksum = "51d1075c37807dcf850c379432f0df05ba52cc30f279c5cfc43cc221ce7f8579" 547 | dependencies = [ 548 | "cc", 549 | "cxxbridge-flags", 550 | "cxxbridge-macro", 551 | "link-cplusplus", 552 | ] 553 | 554 | [[package]] 555 | name = "cxx-build" 556 | version = "1.0.86" 557 | source = "registry+https://github.com/rust-lang/crates.io-index" 558 | checksum = "5044281f61b27bc598f2f6647d480aed48d2bf52d6eb0b627d84c0361b17aa70" 559 | dependencies = [ 560 | "cc", 561 | "codespan-reporting", 562 | "once_cell", 563 | "proc-macro2", 564 | "quote", 565 | "scratch", 566 | "syn 1.0.107", 567 | ] 568 | 569 | [[package]] 570 | name = "cxxbridge-flags" 571 | version = "1.0.86" 572 | source = "registry+https://github.com/rust-lang/crates.io-index" 573 | checksum = "61b50bc93ba22c27b0d31128d2d130a0a6b3d267ae27ef7e4fae2167dfe8781c" 574 | 575 | [[package]] 576 | name = "cxxbridge-macro" 577 | version = "1.0.86" 578 | source = "registry+https://github.com/rust-lang/crates.io-index" 579 | checksum = "39e61fda7e62115119469c7b3591fd913ecca96fb766cfd3f2e2502ab7bc87a5" 580 | dependencies = [ 581 | "proc-macro2", 582 | "quote", 583 | "syn 1.0.107", 584 | ] 585 | 586 | [[package]] 587 | name = "digest" 588 | version = "0.10.6" 589 | source = "registry+https://github.com/rust-lang/crates.io-index" 590 | checksum = "8168378f4e5023e7218c89c891c0fd8ecdb5e5e4f18cb78f38cf245dd021e76f" 591 | dependencies = [ 592 | "block-buffer", 593 | "crypto-common", 594 | "subtle", 595 | ] 596 | 597 | [[package]] 598 | name = "either" 599 | version = "1.8.0" 600 | source = "registry+https://github.com/rust-lang/crates.io-index" 601 | checksum = "90e5c1c8368803113bf0c9584fc495a58b86dc8a29edbf8fe877d21d9507e797" 602 | 603 | [[package]] 604 | name = "equivalent" 605 | version = "1.0.1" 606 | source = "registry+https://github.com/rust-lang/crates.io-index" 607 | checksum = "5443807d6dff69373d433ab9ef5378ad8df50ca6298caf15de6e52e24aaf54d5" 608 | 609 | [[package]] 610 | name = "fastrand" 611 | version = "2.1.0" 612 | source = "registry+https://github.com/rust-lang/crates.io-index" 613 | checksum = "9fc0510504f03c51ada170672ac806f1f105a88aa97a5281117e1ddc3368e51a" 614 | 615 | [[package]] 616 | name = "fnv" 617 | version = "1.0.7" 618 | source = "registry+https://github.com/rust-lang/crates.io-index" 619 | checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" 620 | 621 | [[package]] 622 | name = "form_urlencoded" 623 | version = "1.1.0" 624 | source = "registry+https://github.com/rust-lang/crates.io-index" 625 | checksum = "a9c384f161156f5260c24a097c56119f9be8c798586aecc13afbcbe7b7e26bf8" 626 | dependencies = [ 627 | "percent-encoding", 628 | ] 629 | 630 | [[package]] 631 | name = "futures" 632 | version = "0.3.30" 633 | source = "registry+https://github.com/rust-lang/crates.io-index" 634 | checksum = "645c6916888f6cb6350d2550b80fb63e734897a8498abe35cfb732b6487804b0" 635 | dependencies = [ 636 | "futures-channel", 637 | "futures-core", 638 | "futures-executor", 639 | "futures-io", 640 | "futures-sink", 641 | "futures-task", 642 | "futures-util", 643 | ] 644 | 645 | [[package]] 646 | name = "futures-channel" 647 | version = "0.3.30" 648 | source = "registry+https://github.com/rust-lang/crates.io-index" 649 | checksum = "eac8f7d7865dcb88bd4373ab671c8cf4508703796caa2b1985a9ca867b3fcb78" 650 | dependencies = [ 651 | "futures-core", 652 | "futures-sink", 653 | ] 654 | 655 | [[package]] 656 | name = "futures-core" 657 | version = "0.3.30" 658 | source = "registry+https://github.com/rust-lang/crates.io-index" 659 | checksum = "dfc6580bb841c5a68e9ef15c77ccc837b40a7504914d52e47b8b0e9bbda25a1d" 660 | 661 | [[package]] 662 | name = "futures-executor" 663 | version = "0.3.30" 664 | source = "registry+https://github.com/rust-lang/crates.io-index" 665 | checksum = "a576fc72ae164fca6b9db127eaa9a9dda0d61316034f33a0a0d4eda41f02b01d" 666 | dependencies = [ 667 | "futures-core", 668 | "futures-task", 669 | "futures-util", 670 | ] 671 | 672 | [[package]] 673 | name = "futures-io" 674 | version = "0.3.30" 675 | source = "registry+https://github.com/rust-lang/crates.io-index" 676 | checksum = "a44623e20b9681a318efdd71c299b6b222ed6f231972bfe2f224ebad6311f0c1" 677 | 678 | [[package]] 679 | name = "futures-macro" 680 | version = "0.3.30" 681 | source = "registry+https://github.com/rust-lang/crates.io-index" 682 | checksum = "87750cf4b7a4c0625b1529e4c543c2182106e4dedc60a2a6455e00d212c489ac" 683 | dependencies = [ 684 | "proc-macro2", 685 | "quote", 686 | "syn 2.0.66", 687 | ] 688 | 689 | [[package]] 690 | name = "futures-sink" 691 | version = "0.3.30" 692 | source = "registry+https://github.com/rust-lang/crates.io-index" 693 | checksum = "9fb8e00e87438d937621c1c6269e53f536c14d3fbd6a042bb24879e57d474fb5" 694 | 695 | [[package]] 696 | name = "futures-task" 697 | version = "0.3.30" 698 | source = "registry+https://github.com/rust-lang/crates.io-index" 699 | checksum = "38d84fa142264698cdce1a9f9172cf383a0c82de1bddcf3092901442c4097004" 700 | 701 | [[package]] 702 | name = "futures-util" 703 | version = "0.3.30" 704 | source = "registry+https://github.com/rust-lang/crates.io-index" 705 | checksum = "3d6401deb83407ab3da39eba7e33987a73c3df0c82b4bb5813ee871c19c41d48" 706 | dependencies = [ 707 | "futures-channel", 708 | "futures-core", 709 | "futures-io", 710 | "futures-macro", 711 | "futures-sink", 712 | "futures-task", 713 | "memchr", 714 | "pin-project-lite", 715 | "pin-utils", 716 | "slab", 717 | ] 718 | 719 | [[package]] 720 | name = "generic-array" 721 | version = "0.14.6" 722 | source = "registry+https://github.com/rust-lang/crates.io-index" 723 | checksum = "bff49e947297f3312447abdca79f45f4738097cc82b06e72054d2223f601f1b9" 724 | dependencies = [ 725 | "typenum", 726 | "version_check", 727 | ] 728 | 729 | [[package]] 730 | name = "getrandom" 731 | version = "0.2.15" 732 | source = "registry+https://github.com/rust-lang/crates.io-index" 733 | checksum = "c4567c8db10ae91089c99af84c68c38da3ec2f087c3f82960bcdbf3656b6f4d7" 734 | dependencies = [ 735 | "cfg-if", 736 | "libc", 737 | "wasi 0.11.0+wasi-snapshot-preview1", 738 | ] 739 | 740 | [[package]] 741 | name = "gimli" 742 | version = "0.29.0" 743 | source = "registry+https://github.com/rust-lang/crates.io-index" 744 | checksum = "40ecd4077b5ae9fd2e9e169b102c6c330d0605168eb0e8bf79952b256dbefffd" 745 | 746 | [[package]] 747 | name = "h2" 748 | version = "0.3.26" 749 | source = "registry+https://github.com/rust-lang/crates.io-index" 750 | checksum = "81fe527a889e1532da5c525686d96d4c2e74cdd345badf8dfef9f6b39dd5f5e8" 751 | dependencies = [ 752 | "bytes", 753 | "fnv", 754 | "futures-core", 755 | "futures-sink", 756 | "futures-util", 757 | "http 0.2.12", 758 | "indexmap", 759 | "slab", 760 | "tokio", 761 | "tokio-util", 762 | "tracing", 763 | ] 764 | 765 | [[package]] 766 | name = "hashbrown" 767 | version = "0.14.5" 768 | source = "registry+https://github.com/rust-lang/crates.io-index" 769 | checksum = "e5274423e17b7c9fc20b6e7e208532f9b19825d82dfd615708b70edd83df41f1" 770 | 771 | [[package]] 772 | name = "hermit-abi" 773 | version = "0.2.6" 774 | source = "registry+https://github.com/rust-lang/crates.io-index" 775 | checksum = "ee512640fe35acbfb4bb779db6f0d80704c2cacfa2e39b601ef3e3f47d1ae4c7" 776 | dependencies = [ 777 | "libc", 778 | ] 779 | 780 | [[package]] 781 | name = "hex" 782 | version = "0.4.3" 783 | source = "registry+https://github.com/rust-lang/crates.io-index" 784 | checksum = "7f24254aa9a54b5c858eaee2f5bccdb46aaf0e486a595ed5fd8f86ba55232a70" 785 | 786 | [[package]] 787 | name = "hmac" 788 | version = "0.12.1" 789 | source = "registry+https://github.com/rust-lang/crates.io-index" 790 | checksum = "6c49c37c09c17a53d937dfbb742eb3a961d65a994e6bcdcf37e7399d0cc8ab5e" 791 | dependencies = [ 792 | "digest", 793 | ] 794 | 795 | [[package]] 796 | name = "http" 797 | version = "0.2.12" 798 | source = "registry+https://github.com/rust-lang/crates.io-index" 799 | checksum = "601cbb57e577e2f5ef5be8e7b83f0f63994f25aa94d673e54a92d5c516d101f1" 800 | dependencies = [ 801 | "bytes", 802 | "fnv", 803 | "itoa", 804 | ] 805 | 806 | [[package]] 807 | name = "http" 808 | version = "1.1.0" 809 | source = "registry+https://github.com/rust-lang/crates.io-index" 810 | checksum = "21b9ddb458710bc376481b842f5da65cdf31522de232c1ca8146abce2a358258" 811 | dependencies = [ 812 | "bytes", 813 | "fnv", 814 | "itoa", 815 | ] 816 | 817 | [[package]] 818 | name = "http-body" 819 | version = "0.4.5" 820 | source = "registry+https://github.com/rust-lang/crates.io-index" 821 | checksum = "d5f38f16d184e36f2408a55281cd658ecbd3ca05cce6d6510a176eca393e26d1" 822 | dependencies = [ 823 | "bytes", 824 | "http 0.2.12", 825 | "pin-project-lite", 826 | ] 827 | 828 | [[package]] 829 | name = "http-body" 830 | version = "1.0.0" 831 | source = "registry+https://github.com/rust-lang/crates.io-index" 832 | checksum = "1cac85db508abc24a2e48553ba12a996e87244a0395ce011e62b37158745d643" 833 | dependencies = [ 834 | "bytes", 835 | "http 1.1.0", 836 | ] 837 | 838 | [[package]] 839 | name = "http-body-util" 840 | version = "0.1.2" 841 | source = "registry+https://github.com/rust-lang/crates.io-index" 842 | checksum = "793429d76616a256bcb62c2a2ec2bed781c8307e797e2598c50010f2bee2544f" 843 | dependencies = [ 844 | "bytes", 845 | "futures-util", 846 | "http 1.1.0", 847 | "http-body 1.0.0", 848 | "pin-project-lite", 849 | ] 850 | 851 | [[package]] 852 | name = "httparse" 853 | version = "1.8.0" 854 | source = "registry+https://github.com/rust-lang/crates.io-index" 855 | checksum = "d897f394bad6a705d5f4104762e116a75639e470d80901eed05a860a95cb1904" 856 | 857 | [[package]] 858 | name = "httpdate" 859 | version = "1.0.2" 860 | source = "registry+https://github.com/rust-lang/crates.io-index" 861 | checksum = "c4a1e36c821dbe04574f602848a19f742f4fb3c98d40449f11bcad18d6b17421" 862 | 863 | [[package]] 864 | name = "hyper" 865 | version = "0.14.29" 866 | source = "registry+https://github.com/rust-lang/crates.io-index" 867 | checksum = "f361cde2f109281a220d4307746cdfd5ee3f410da58a70377762396775634b33" 868 | dependencies = [ 869 | "bytes", 870 | "futures-channel", 871 | "futures-core", 872 | "futures-util", 873 | "h2", 874 | "http 0.2.12", 875 | "http-body 0.4.5", 876 | "httparse", 877 | "httpdate", 878 | "itoa", 879 | "pin-project-lite", 880 | "socket2", 881 | "tokio", 882 | "tower-service", 883 | "tracing", 884 | "want", 885 | ] 886 | 887 | [[package]] 888 | name = "hyper" 889 | version = "1.3.1" 890 | source = "registry+https://github.com/rust-lang/crates.io-index" 891 | checksum = "fe575dd17d0862a9a33781c8c4696a55c320909004a67a00fb286ba8b1bc496d" 892 | dependencies = [ 893 | "bytes", 894 | "futures-channel", 895 | "futures-util", 896 | "http 1.1.0", 897 | "http-body 1.0.0", 898 | "httparse", 899 | "httpdate", 900 | "itoa", 901 | "pin-project-lite", 902 | "smallvec", 903 | "tokio", 904 | "want", 905 | ] 906 | 907 | [[package]] 908 | name = "hyper-rustls" 909 | version = "0.24.2" 910 | source = "registry+https://github.com/rust-lang/crates.io-index" 911 | checksum = "ec3efd23720e2049821a693cbc7e65ea87c72f1c58ff2f9522ff332b1491e590" 912 | dependencies = [ 913 | "futures-util", 914 | "http 0.2.12", 915 | "hyper 0.14.29", 916 | "log", 917 | "rustls", 918 | "rustls-native-certs", 919 | "tokio", 920 | "tokio-rustls", 921 | ] 922 | 923 | [[package]] 924 | name = "hyper-util" 925 | version = "0.1.5" 926 | source = "registry+https://github.com/rust-lang/crates.io-index" 927 | checksum = "7b875924a60b96e5d7b9ae7b066540b1dd1cbd90d1828f54c92e02a283351c56" 928 | dependencies = [ 929 | "bytes", 930 | "futures-channel", 931 | "futures-util", 932 | "http 1.1.0", 933 | "http-body 1.0.0", 934 | "hyper 1.3.1", 935 | "pin-project-lite", 936 | "socket2", 937 | "tokio", 938 | "tower", 939 | "tower-service", 940 | "tracing", 941 | ] 942 | 943 | [[package]] 944 | name = "iana-time-zone" 945 | version = "0.1.53" 946 | source = "registry+https://github.com/rust-lang/crates.io-index" 947 | checksum = "64c122667b287044802d6ce17ee2ddf13207ed924c712de9a66a5814d5b64765" 948 | dependencies = [ 949 | "android_system_properties", 950 | "core-foundation-sys", 951 | "iana-time-zone-haiku", 952 | "js-sys", 953 | "wasm-bindgen", 954 | "winapi", 955 | ] 956 | 957 | [[package]] 958 | name = "iana-time-zone-haiku" 959 | version = "0.1.1" 960 | source = "registry+https://github.com/rust-lang/crates.io-index" 961 | checksum = "0703ae284fc167426161c2e3f1da3ea71d94b21bedbcc9494e92b28e334e3dca" 962 | dependencies = [ 963 | "cxx", 964 | "cxx-build", 965 | ] 966 | 967 | [[package]] 968 | name = "idna" 969 | version = "0.3.0" 970 | source = "registry+https://github.com/rust-lang/crates.io-index" 971 | checksum = "e14ddfc70884202db2244c223200c204c2bda1bc6e0998d11b5e024d657209e6" 972 | dependencies = [ 973 | "unicode-bidi", 974 | "unicode-normalization", 975 | ] 976 | 977 | [[package]] 978 | name = "indexmap" 979 | version = "2.2.6" 980 | source = "registry+https://github.com/rust-lang/crates.io-index" 981 | checksum = "168fb715dda47215e360912c096649d23d58bf392ac62f73919e831745e40f26" 982 | dependencies = [ 983 | "equivalent", 984 | "hashbrown", 985 | ] 986 | 987 | [[package]] 988 | name = "itoa" 989 | version = "1.0.5" 990 | source = "registry+https://github.com/rust-lang/crates.io-index" 991 | checksum = "fad582f4b9e86b6caa621cabeb0963332d92eea04729ab12892c2533951e6440" 992 | 993 | [[package]] 994 | name = "js-sys" 995 | version = "0.3.60" 996 | source = "registry+https://github.com/rust-lang/crates.io-index" 997 | checksum = "49409df3e3bf0856b916e2ceaca09ee28e6871cf7d9ce97a692cacfdb2a25a47" 998 | dependencies = [ 999 | "wasm-bindgen", 1000 | ] 1001 | 1002 | [[package]] 1003 | name = "lambda-extension" 1004 | version = "0.10.0" 1005 | source = "registry+https://github.com/rust-lang/crates.io-index" 1006 | checksum = "23214b203ecdf1f99dcec733aa03399cfa24293ec53ddceef30f85bd0ef7085a" 1007 | dependencies = [ 1008 | "async-stream", 1009 | "bytes", 1010 | "chrono", 1011 | "http 1.1.0", 1012 | "http-body-util", 1013 | "hyper 1.3.1", 1014 | "hyper-util", 1015 | "lambda_runtime_api_client", 1016 | "serde", 1017 | "serde_json", 1018 | "tokio", 1019 | "tokio-stream", 1020 | "tower", 1021 | "tracing", 1022 | ] 1023 | 1024 | [[package]] 1025 | name = "lambda_runtime_api_client" 1026 | version = "0.10.0" 1027 | source = "registry+https://github.com/rust-lang/crates.io-index" 1028 | checksum = "1364cd67281721d2a9a4444ba555cf4d74a195e647061fa4ccac46e6f5c3b0ae" 1029 | dependencies = [ 1030 | "bytes", 1031 | "futures-channel", 1032 | "futures-util", 1033 | "http 1.1.0", 1034 | "http-body 1.0.0", 1035 | "http-body-util", 1036 | "hyper 1.3.1", 1037 | "hyper-util", 1038 | "tokio", 1039 | "tower", 1040 | "tower-service", 1041 | "tracing", 1042 | "tracing-subscriber", 1043 | ] 1044 | 1045 | [[package]] 1046 | name = "lazy_static" 1047 | version = "1.4.0" 1048 | source = "registry+https://github.com/rust-lang/crates.io-index" 1049 | checksum = "e2abad23fbc42b3700f2f279844dc832adb2b2eb069b2df918f455c4e18cc646" 1050 | 1051 | [[package]] 1052 | name = "libc" 1053 | version = "0.2.155" 1054 | source = "registry+https://github.com/rust-lang/crates.io-index" 1055 | checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" 1056 | 1057 | [[package]] 1058 | name = "link-cplusplus" 1059 | version = "1.0.8" 1060 | source = "registry+https://github.com/rust-lang/crates.io-index" 1061 | checksum = "ecd207c9c713c34f95a097a5b029ac2ce6010530c7b49d7fea24d977dede04f5" 1062 | dependencies = [ 1063 | "cc", 1064 | ] 1065 | 1066 | [[package]] 1067 | name = "lock_api" 1068 | version = "0.4.9" 1069 | source = "registry+https://github.com/rust-lang/crates.io-index" 1070 | checksum = "435011366fe56583b16cf956f9df0095b405b82d76425bc8981c0e22e60ec4df" 1071 | dependencies = [ 1072 | "autocfg", 1073 | "scopeguard", 1074 | ] 1075 | 1076 | [[package]] 1077 | name = "log" 1078 | version = "0.4.17" 1079 | source = "registry+https://github.com/rust-lang/crates.io-index" 1080 | checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" 1081 | dependencies = [ 1082 | "cfg-if", 1083 | ] 1084 | 1085 | [[package]] 1086 | name = "matchers" 1087 | version = "0.1.0" 1088 | source = "registry+https://github.com/rust-lang/crates.io-index" 1089 | checksum = "8263075bb86c5a1b1427b5ae862e8889656f126e9f77c484496e8b47cf5c5558" 1090 | dependencies = [ 1091 | "regex-automata", 1092 | ] 1093 | 1094 | [[package]] 1095 | name = "memchr" 1096 | version = "2.5.0" 1097 | source = "registry+https://github.com/rust-lang/crates.io-index" 1098 | checksum = "2dffe52ecf27772e601905b7522cb4ef790d2cc203488bbd0e2fe85fcb74566d" 1099 | 1100 | [[package]] 1101 | name = "miniz_oxide" 1102 | version = "0.7.4" 1103 | source = "registry+https://github.com/rust-lang/crates.io-index" 1104 | checksum = "b8a240ddb74feaf34a79a7add65a741f3167852fba007066dcac1ca548d89c08" 1105 | dependencies = [ 1106 | "adler", 1107 | ] 1108 | 1109 | [[package]] 1110 | name = "mio" 1111 | version = "0.8.11" 1112 | source = "registry+https://github.com/rust-lang/crates.io-index" 1113 | checksum = "a4a650543ca06a924e8b371db273b2756685faae30f8487da1b56505a8f78b0c" 1114 | dependencies = [ 1115 | "libc", 1116 | "wasi 0.11.0+wasi-snapshot-preview1", 1117 | "windows-sys 0.48.0", 1118 | ] 1119 | 1120 | [[package]] 1121 | name = "num-integer" 1122 | version = "0.1.45" 1123 | source = "registry+https://github.com/rust-lang/crates.io-index" 1124 | checksum = "225d3389fb3509a24c93f5c29eb6bde2586b98d9f016636dff58d7c6f7569cd9" 1125 | dependencies = [ 1126 | "autocfg", 1127 | "num-traits", 1128 | ] 1129 | 1130 | [[package]] 1131 | name = "num-traits" 1132 | version = "0.2.15" 1133 | source = "registry+https://github.com/rust-lang/crates.io-index" 1134 | checksum = "578ede34cf02f8924ab9447f50c28075b4d3e5b269972345e7e0372b38c6cdcd" 1135 | dependencies = [ 1136 | "autocfg", 1137 | ] 1138 | 1139 | [[package]] 1140 | name = "num_cpus" 1141 | version = "1.15.0" 1142 | source = "registry+https://github.com/rust-lang/crates.io-index" 1143 | checksum = "0fac9e2da13b5eb447a6ce3d392f23a29d8694bff781bf03a16cd9ac8697593b" 1144 | dependencies = [ 1145 | "hermit-abi", 1146 | "libc", 1147 | ] 1148 | 1149 | [[package]] 1150 | name = "object" 1151 | version = "0.36.0" 1152 | source = "registry+https://github.com/rust-lang/crates.io-index" 1153 | checksum = "576dfe1fc8f9df304abb159d767a29d0476f7750fbf8aa7ad07816004a207434" 1154 | dependencies = [ 1155 | "memchr", 1156 | ] 1157 | 1158 | [[package]] 1159 | name = "once_cell" 1160 | version = "1.19.0" 1161 | source = "registry+https://github.com/rust-lang/crates.io-index" 1162 | checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" 1163 | 1164 | [[package]] 1165 | name = "openssl-probe" 1166 | version = "0.1.5" 1167 | source = "registry+https://github.com/rust-lang/crates.io-index" 1168 | checksum = "ff011a302c396a5197692431fc1948019154afc178baf7d8e37367442a4601cf" 1169 | 1170 | [[package]] 1171 | name = "outref" 1172 | version = "0.5.1" 1173 | source = "registry+https://github.com/rust-lang/crates.io-index" 1174 | checksum = "4030760ffd992bef45b0ae3f10ce1aba99e33464c90d14dd7c039884963ddc7a" 1175 | 1176 | [[package]] 1177 | name = "parking_lot" 1178 | version = "0.12.1" 1179 | source = "registry+https://github.com/rust-lang/crates.io-index" 1180 | checksum = "3742b2c103b9f06bc9fff0a37ff4912935851bee6d36f3c02bcc755bcfec228f" 1181 | dependencies = [ 1182 | "lock_api", 1183 | "parking_lot_core", 1184 | ] 1185 | 1186 | [[package]] 1187 | name = "parking_lot_core" 1188 | version = "0.9.6" 1189 | source = "registry+https://github.com/rust-lang/crates.io-index" 1190 | checksum = "ba1ef8814b5c993410bb3adfad7a5ed269563e4a2f90c41f5d85be7fb47133bf" 1191 | dependencies = [ 1192 | "cfg-if", 1193 | "libc", 1194 | "redox_syscall", 1195 | "smallvec", 1196 | "windows-sys 0.42.0", 1197 | ] 1198 | 1199 | [[package]] 1200 | name = "percent-encoding" 1201 | version = "2.2.0" 1202 | source = "registry+https://github.com/rust-lang/crates.io-index" 1203 | checksum = "478c572c3d73181ff3c2539045f6eb99e5491218eae919370993b890cdbdd98e" 1204 | 1205 | [[package]] 1206 | name = "pin-project" 1207 | version = "1.0.12" 1208 | source = "registry+https://github.com/rust-lang/crates.io-index" 1209 | checksum = "ad29a609b6bcd67fee905812e544992d216af9d755757c05ed2d0e15a74c6ecc" 1210 | dependencies = [ 1211 | "pin-project-internal", 1212 | ] 1213 | 1214 | [[package]] 1215 | name = "pin-project-internal" 1216 | version = "1.0.12" 1217 | source = "registry+https://github.com/rust-lang/crates.io-index" 1218 | checksum = "069bdb1e05adc7a8990dce9cc75370895fbe4e3d58b9b73bf1aee56359344a55" 1219 | dependencies = [ 1220 | "proc-macro2", 1221 | "quote", 1222 | "syn 1.0.107", 1223 | ] 1224 | 1225 | [[package]] 1226 | name = "pin-project-lite" 1227 | version = "0.2.14" 1228 | source = "registry+https://github.com/rust-lang/crates.io-index" 1229 | checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" 1230 | 1231 | [[package]] 1232 | name = "pin-utils" 1233 | version = "0.1.0" 1234 | source = "registry+https://github.com/rust-lang/crates.io-index" 1235 | checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" 1236 | 1237 | [[package]] 1238 | name = "proc-macro2" 1239 | version = "1.0.85" 1240 | source = "registry+https://github.com/rust-lang/crates.io-index" 1241 | checksum = "22244ce15aa966053a896d1accb3a6e68469b97c7f33f284b99f0d576879fc23" 1242 | dependencies = [ 1243 | "unicode-ident", 1244 | ] 1245 | 1246 | [[package]] 1247 | name = "quote" 1248 | version = "1.0.36" 1249 | source = "registry+https://github.com/rust-lang/crates.io-index" 1250 | checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" 1251 | dependencies = [ 1252 | "proc-macro2", 1253 | ] 1254 | 1255 | [[package]] 1256 | name = "redhook" 1257 | version = "2.0.0" 1258 | source = "registry+https://github.com/rust-lang/crates.io-index" 1259 | checksum = "b6e109b8469dbbe6d7cbe18e5ebd65d4a134e2f4b91304ad9213984cad1d70a6" 1260 | dependencies = [ 1261 | "libc", 1262 | ] 1263 | 1264 | [[package]] 1265 | name = "redox_syscall" 1266 | version = "0.2.16" 1267 | source = "registry+https://github.com/rust-lang/crates.io-index" 1268 | checksum = "fb5a58c1855b4b6819d59012155603f0b22ad30cad752600aadfcb695265519a" 1269 | dependencies = [ 1270 | "bitflags", 1271 | ] 1272 | 1273 | [[package]] 1274 | name = "regex" 1275 | version = "1.7.1" 1276 | source = "registry+https://github.com/rust-lang/crates.io-index" 1277 | checksum = "48aaa5748ba571fb95cd2c85c09f629215d3a6ece942baa100950af03a34f733" 1278 | dependencies = [ 1279 | "regex-syntax", 1280 | ] 1281 | 1282 | [[package]] 1283 | name = "regex-automata" 1284 | version = "0.1.10" 1285 | source = "registry+https://github.com/rust-lang/crates.io-index" 1286 | checksum = "6c230d73fb8d8c1b9c0b3135c5142a8acee3a0558fb8db5cf1cb65f8d7862132" 1287 | dependencies = [ 1288 | "regex-syntax", 1289 | ] 1290 | 1291 | [[package]] 1292 | name = "regex-lite" 1293 | version = "0.1.6" 1294 | source = "registry+https://github.com/rust-lang/crates.io-index" 1295 | checksum = "53a49587ad06b26609c52e423de037e7f57f20d53535d66e08c695f347df952a" 1296 | 1297 | [[package]] 1298 | name = "regex-syntax" 1299 | version = "0.6.28" 1300 | source = "registry+https://github.com/rust-lang/crates.io-index" 1301 | checksum = "456c603be3e8d448b072f410900c09faf164fbce2d480456f50eea6e25f9c848" 1302 | 1303 | [[package]] 1304 | name = "ring" 1305 | version = "0.16.20" 1306 | source = "registry+https://github.com/rust-lang/crates.io-index" 1307 | checksum = "3053cf52e236a3ed746dfc745aa9cacf1b791d846bdaf412f60a8d7d6e17c8fc" 1308 | dependencies = [ 1309 | "cc", 1310 | "libc", 1311 | "once_cell", 1312 | "spin 0.5.2", 1313 | "untrusted 0.7.1", 1314 | "web-sys", 1315 | "winapi", 1316 | ] 1317 | 1318 | [[package]] 1319 | name = "ring" 1320 | version = "0.17.8" 1321 | source = "registry+https://github.com/rust-lang/crates.io-index" 1322 | checksum = "c17fa4cb658e3583423e915b9f3acc01cceaee1860e33d59ebae66adc3a2dc0d" 1323 | dependencies = [ 1324 | "cc", 1325 | "cfg-if", 1326 | "getrandom", 1327 | "libc", 1328 | "spin 0.9.8", 1329 | "untrusted 0.9.0", 1330 | "windows-sys 0.52.0", 1331 | ] 1332 | 1333 | [[package]] 1334 | name = "rustc-demangle" 1335 | version = "0.1.24" 1336 | source = "registry+https://github.com/rust-lang/crates.io-index" 1337 | checksum = "719b953e2095829ee67db738b3bfa9fa368c94900df327b3f07fe6e794d2fe1f" 1338 | 1339 | [[package]] 1340 | name = "rustc_version" 1341 | version = "0.4.0" 1342 | source = "registry+https://github.com/rust-lang/crates.io-index" 1343 | checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366" 1344 | dependencies = [ 1345 | "semver", 1346 | ] 1347 | 1348 | [[package]] 1349 | name = "rustls" 1350 | version = "0.21.12" 1351 | source = "registry+https://github.com/rust-lang/crates.io-index" 1352 | checksum = "3f56a14d1f48b391359b22f731fd4bd7e43c97f3c50eee276f3aa09c94784d3e" 1353 | dependencies = [ 1354 | "log", 1355 | "ring 0.17.8", 1356 | "rustls-webpki", 1357 | "sct", 1358 | ] 1359 | 1360 | [[package]] 1361 | name = "rustls-native-certs" 1362 | version = "0.6.2" 1363 | source = "registry+https://github.com/rust-lang/crates.io-index" 1364 | checksum = "0167bac7a9f490495f3c33013e7722b53cb087ecbe082fb0c6387c96f634ea50" 1365 | dependencies = [ 1366 | "openssl-probe", 1367 | "rustls-pemfile", 1368 | "schannel", 1369 | "security-framework", 1370 | ] 1371 | 1372 | [[package]] 1373 | name = "rustls-pemfile" 1374 | version = "1.0.2" 1375 | source = "registry+https://github.com/rust-lang/crates.io-index" 1376 | checksum = "d194b56d58803a43635bdc398cd17e383d6f71f9182b9a192c127ca42494a59b" 1377 | dependencies = [ 1378 | "base64", 1379 | ] 1380 | 1381 | [[package]] 1382 | name = "rustls-webpki" 1383 | version = "0.101.7" 1384 | source = "registry+https://github.com/rust-lang/crates.io-index" 1385 | checksum = "8b6275d1ee7a1cd780b64aca7726599a1dbc893b1e64144529e55c3c2f745765" 1386 | dependencies = [ 1387 | "ring 0.17.8", 1388 | "untrusted 0.9.0", 1389 | ] 1390 | 1391 | [[package]] 1392 | name = "ryu" 1393 | version = "1.0.12" 1394 | source = "registry+https://github.com/rust-lang/crates.io-index" 1395 | checksum = "7b4b9743ed687d4b4bcedf9ff5eaa7398495ae14e61cba0a295704edbc7decde" 1396 | 1397 | [[package]] 1398 | name = "schannel" 1399 | version = "0.1.21" 1400 | source = "registry+https://github.com/rust-lang/crates.io-index" 1401 | checksum = "713cfb06c7059f3588fb8044c0fad1d09e3c01d225e25b9220dbfdcf16dbb1b3" 1402 | dependencies = [ 1403 | "windows-sys 0.42.0", 1404 | ] 1405 | 1406 | [[package]] 1407 | name = "scopeguard" 1408 | version = "1.1.0" 1409 | source = "registry+https://github.com/rust-lang/crates.io-index" 1410 | checksum = "d29ab0c6d3fc0ee92fe66e2d99f700eab17a8d57d1c1d3b748380fb20baa78cd" 1411 | 1412 | [[package]] 1413 | name = "scratch" 1414 | version = "1.0.3" 1415 | source = "registry+https://github.com/rust-lang/crates.io-index" 1416 | checksum = "ddccb15bcce173023b3fedd9436f882a0739b8dfb45e4f6b6002bee5929f61b2" 1417 | 1418 | [[package]] 1419 | name = "sct" 1420 | version = "0.7.0" 1421 | source = "registry+https://github.com/rust-lang/crates.io-index" 1422 | checksum = "d53dcdb7c9f8158937a7981b48accfd39a43af418591a5d008c7b22b5e1b7ca4" 1423 | dependencies = [ 1424 | "ring 0.16.20", 1425 | "untrusted 0.7.1", 1426 | ] 1427 | 1428 | [[package]] 1429 | name = "security-framework" 1430 | version = "2.8.0" 1431 | source = "registry+https://github.com/rust-lang/crates.io-index" 1432 | checksum = "645926f31b250a2dca3c232496c2d898d91036e45ca0e97e0e2390c54e11be36" 1433 | dependencies = [ 1434 | "bitflags", 1435 | "core-foundation", 1436 | "core-foundation-sys", 1437 | "libc", 1438 | "security-framework-sys", 1439 | ] 1440 | 1441 | [[package]] 1442 | name = "security-framework-sys" 1443 | version = "2.8.0" 1444 | source = "registry+https://github.com/rust-lang/crates.io-index" 1445 | checksum = "31c9bb296072e961fcbd8853511dd39c2d8be2deb1e17c6860b1d30732b323b4" 1446 | dependencies = [ 1447 | "core-foundation-sys", 1448 | "libc", 1449 | ] 1450 | 1451 | [[package]] 1452 | name = "semver" 1453 | version = "1.0.16" 1454 | source = "registry+https://github.com/rust-lang/crates.io-index" 1455 | checksum = "58bc9567378fc7690d6b2addae4e60ac2eeea07becb2c64b9f218b53865cba2a" 1456 | 1457 | [[package]] 1458 | name = "serde" 1459 | version = "1.0.203" 1460 | source = "registry+https://github.com/rust-lang/crates.io-index" 1461 | checksum = "7253ab4de971e72fb7be983802300c30b5a7f0c2e56fab8abfc6a214307c0094" 1462 | dependencies = [ 1463 | "serde_derive", 1464 | ] 1465 | 1466 | [[package]] 1467 | name = "serde_derive" 1468 | version = "1.0.203" 1469 | source = "registry+https://github.com/rust-lang/crates.io-index" 1470 | checksum = "500cbc0ebeb6f46627f50f3f5811ccf6bf00643be300b4c3eabc0ef55dc5b5ba" 1471 | dependencies = [ 1472 | "proc-macro2", 1473 | "quote", 1474 | "syn 2.0.66", 1475 | ] 1476 | 1477 | [[package]] 1478 | name = "serde_json" 1479 | version = "1.0.117" 1480 | source = "registry+https://github.com/rust-lang/crates.io-index" 1481 | checksum = "455182ea6142b14f93f4bc5320a2b31c1f266b66a4a5c858b013302a5d8cbfc3" 1482 | dependencies = [ 1483 | "itoa", 1484 | "ryu", 1485 | "serde", 1486 | ] 1487 | 1488 | [[package]] 1489 | name = "sha2" 1490 | version = "0.10.6" 1491 | source = "registry+https://github.com/rust-lang/crates.io-index" 1492 | checksum = "82e6b795fe2e3b1e845bafcb27aa35405c4d47cdfc92af5fc8d3002f76cebdc0" 1493 | dependencies = [ 1494 | "cfg-if", 1495 | "cpufeatures", 1496 | "digest", 1497 | ] 1498 | 1499 | [[package]] 1500 | name = "sharded-slab" 1501 | version = "0.1.7" 1502 | source = "registry+https://github.com/rust-lang/crates.io-index" 1503 | checksum = "f40ca3c46823713e0d4209592e8d6e826aa57e928f09752619fc696c499637f6" 1504 | dependencies = [ 1505 | "lazy_static", 1506 | ] 1507 | 1508 | [[package]] 1509 | name = "signal-hook-registry" 1510 | version = "1.4.0" 1511 | source = "registry+https://github.com/rust-lang/crates.io-index" 1512 | checksum = "e51e73328dc4ac0c7ccbda3a494dfa03df1de2f46018127f60c693f2648455b0" 1513 | dependencies = [ 1514 | "libc", 1515 | ] 1516 | 1517 | [[package]] 1518 | name = "slab" 1519 | version = "0.4.7" 1520 | source = "registry+https://github.com/rust-lang/crates.io-index" 1521 | checksum = "4614a76b2a8be0058caa9dbbaf66d988527d86d003c11a94fbd335d7661edcef" 1522 | dependencies = [ 1523 | "autocfg", 1524 | ] 1525 | 1526 | [[package]] 1527 | name = "smallvec" 1528 | version = "1.13.2" 1529 | source = "registry+https://github.com/rust-lang/crates.io-index" 1530 | checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" 1531 | 1532 | [[package]] 1533 | name = "socket2" 1534 | version = "0.5.7" 1535 | source = "registry+https://github.com/rust-lang/crates.io-index" 1536 | checksum = "ce305eb0b4296696835b71df73eb912e0f1ffd2556a501fcede6e0c50349191c" 1537 | dependencies = [ 1538 | "libc", 1539 | "windows-sys 0.52.0", 1540 | ] 1541 | 1542 | [[package]] 1543 | name = "spin" 1544 | version = "0.5.2" 1545 | source = "registry+https://github.com/rust-lang/crates.io-index" 1546 | checksum = "6e63cff320ae2c57904679ba7cb63280a3dc4613885beafb148ee7bf9aa9042d" 1547 | 1548 | [[package]] 1549 | name = "spin" 1550 | version = "0.9.8" 1551 | source = "registry+https://github.com/rust-lang/crates.io-index" 1552 | checksum = "6980e8d7511241f8acf4aebddbb1ff938df5eebe98691418c4468d0b72a96a67" 1553 | 1554 | [[package]] 1555 | name = "subtle" 1556 | version = "2.4.1" 1557 | source = "registry+https://github.com/rust-lang/crates.io-index" 1558 | checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" 1559 | 1560 | [[package]] 1561 | name = "syn" 1562 | version = "1.0.107" 1563 | source = "registry+https://github.com/rust-lang/crates.io-index" 1564 | checksum = "1f4064b5b16e03ae50984a5a8ed5d4f8803e6bc1fd170a3cda91a1be4b18e3f5" 1565 | dependencies = [ 1566 | "proc-macro2", 1567 | "quote", 1568 | "unicode-ident", 1569 | ] 1570 | 1571 | [[package]] 1572 | name = "syn" 1573 | version = "2.0.66" 1574 | source = "registry+https://github.com/rust-lang/crates.io-index" 1575 | checksum = "c42f3f41a2de00b01c0aaad383c5a45241efc8b2d1eda5661812fda5f3cdcff5" 1576 | dependencies = [ 1577 | "proc-macro2", 1578 | "quote", 1579 | "unicode-ident", 1580 | ] 1581 | 1582 | [[package]] 1583 | name = "termcolor" 1584 | version = "1.2.0" 1585 | source = "registry+https://github.com/rust-lang/crates.io-index" 1586 | checksum = "be55cf8942feac5c765c2c993422806843c9a9a45d4d5c407ad6dd2ea95eb9b6" 1587 | dependencies = [ 1588 | "winapi-util", 1589 | ] 1590 | 1591 | [[package]] 1592 | name = "thread_local" 1593 | version = "1.1.8" 1594 | source = "registry+https://github.com/rust-lang/crates.io-index" 1595 | checksum = "8b9ef9bad013ada3808854ceac7b46812a6465ba368859a37e2100283d2d719c" 1596 | dependencies = [ 1597 | "cfg-if", 1598 | "once_cell", 1599 | ] 1600 | 1601 | [[package]] 1602 | name = "time" 1603 | version = "0.1.45" 1604 | source = "registry+https://github.com/rust-lang/crates.io-index" 1605 | checksum = "1b797afad3f312d1c66a56d11d0316f916356d11bd158fbc6ca6389ff6bf805a" 1606 | dependencies = [ 1607 | "libc", 1608 | "wasi 0.10.0+wasi-snapshot-preview1", 1609 | "winapi", 1610 | ] 1611 | 1612 | [[package]] 1613 | name = "time" 1614 | version = "0.3.17" 1615 | source = "registry+https://github.com/rust-lang/crates.io-index" 1616 | checksum = "a561bf4617eebd33bca6434b988f39ed798e527f51a1e797d0ee4f61c0a38376" 1617 | dependencies = [ 1618 | "serde", 1619 | "time-core", 1620 | "time-macros", 1621 | ] 1622 | 1623 | [[package]] 1624 | name = "time-core" 1625 | version = "0.1.0" 1626 | source = "registry+https://github.com/rust-lang/crates.io-index" 1627 | checksum = "2e153e1f1acaef8acc537e68b44906d2db6436e2b35ac2c6b42640fff91f00fd" 1628 | 1629 | [[package]] 1630 | name = "time-macros" 1631 | version = "0.2.6" 1632 | source = "registry+https://github.com/rust-lang/crates.io-index" 1633 | checksum = "d967f99f534ca7e495c575c62638eebc2898a8c84c119b89e250477bc4ba16b2" 1634 | dependencies = [ 1635 | "time-core", 1636 | ] 1637 | 1638 | [[package]] 1639 | name = "tinyvec" 1640 | version = "1.6.0" 1641 | source = "registry+https://github.com/rust-lang/crates.io-index" 1642 | checksum = "87cc5ceb3875bb20c2890005a4e226a4651264a5c75edb2421b52861a0a0cb50" 1643 | dependencies = [ 1644 | "tinyvec_macros", 1645 | ] 1646 | 1647 | [[package]] 1648 | name = "tinyvec_macros" 1649 | version = "0.1.0" 1650 | source = "registry+https://github.com/rust-lang/crates.io-index" 1651 | checksum = "cda74da7e1a664f795bb1f8a87ec406fb89a02522cf6e50620d016add6dbbf5c" 1652 | 1653 | [[package]] 1654 | name = "tokio" 1655 | version = "1.38.0" 1656 | source = "registry+https://github.com/rust-lang/crates.io-index" 1657 | checksum = "ba4f4a02a7a80d6f274636f0aa95c7e383b912d41fe721a31f29e29698585a4a" 1658 | dependencies = [ 1659 | "backtrace", 1660 | "bytes", 1661 | "libc", 1662 | "mio", 1663 | "num_cpus", 1664 | "parking_lot", 1665 | "pin-project-lite", 1666 | "signal-hook-registry", 1667 | "socket2", 1668 | "tokio-macros", 1669 | "windows-sys 0.48.0", 1670 | ] 1671 | 1672 | [[package]] 1673 | name = "tokio-macros" 1674 | version = "2.3.0" 1675 | source = "registry+https://github.com/rust-lang/crates.io-index" 1676 | checksum = "5f5ae998a069d4b5aba8ee9dad856af7d520c3699e6159b185c2acd48155d39a" 1677 | dependencies = [ 1678 | "proc-macro2", 1679 | "quote", 1680 | "syn 2.0.66", 1681 | ] 1682 | 1683 | [[package]] 1684 | name = "tokio-rustls" 1685 | version = "0.24.1" 1686 | source = "registry+https://github.com/rust-lang/crates.io-index" 1687 | checksum = "c28327cf380ac148141087fbfb9de9d7bd4e84ab5d2c28fbc911d753de8a7081" 1688 | dependencies = [ 1689 | "rustls", 1690 | "tokio", 1691 | ] 1692 | 1693 | [[package]] 1694 | name = "tokio-stream" 1695 | version = "0.1.11" 1696 | source = "registry+https://github.com/rust-lang/crates.io-index" 1697 | checksum = "d660770404473ccd7bc9f8b28494a811bc18542b915c0855c51e8f419d5223ce" 1698 | dependencies = [ 1699 | "futures-core", 1700 | "pin-project-lite", 1701 | "tokio", 1702 | ] 1703 | 1704 | [[package]] 1705 | name = "tokio-util" 1706 | version = "0.7.4" 1707 | source = "registry+https://github.com/rust-lang/crates.io-index" 1708 | checksum = "0bb2e075f03b3d66d8d8785356224ba688d2906a371015e225beeb65ca92c740" 1709 | dependencies = [ 1710 | "bytes", 1711 | "futures-core", 1712 | "futures-sink", 1713 | "pin-project-lite", 1714 | "tokio", 1715 | "tracing", 1716 | ] 1717 | 1718 | [[package]] 1719 | name = "tower" 1720 | version = "0.4.13" 1721 | source = "registry+https://github.com/rust-lang/crates.io-index" 1722 | checksum = "b8fa9be0de6cf49e536ce1851f987bd21a43b771b09473c3549a6c853db37c1c" 1723 | dependencies = [ 1724 | "futures-core", 1725 | "futures-util", 1726 | "pin-project", 1727 | "pin-project-lite", 1728 | "tokio", 1729 | "tower-layer", 1730 | "tower-service", 1731 | "tracing", 1732 | ] 1733 | 1734 | [[package]] 1735 | name = "tower-layer" 1736 | version = "0.3.2" 1737 | source = "registry+https://github.com/rust-lang/crates.io-index" 1738 | checksum = "c20c8dbed6283a09604c3e69b4b7eeb54e298b8a600d4d5ecb5ad39de609f1d0" 1739 | 1740 | [[package]] 1741 | name = "tower-service" 1742 | version = "0.3.2" 1743 | source = "registry+https://github.com/rust-lang/crates.io-index" 1744 | checksum = "b6bc1c9ce2b5135ac7f93c72918fc37feb872bdc6a5533a8b85eb4b86bfdae52" 1745 | 1746 | [[package]] 1747 | name = "tracing" 1748 | version = "0.1.37" 1749 | source = "registry+https://github.com/rust-lang/crates.io-index" 1750 | checksum = "8ce8c33a8d48bd45d624a6e523445fd21ec13d3653cd51f681abf67418f54eb8" 1751 | dependencies = [ 1752 | "cfg-if", 1753 | "log", 1754 | "pin-project-lite", 1755 | "tracing-attributes", 1756 | "tracing-core", 1757 | ] 1758 | 1759 | [[package]] 1760 | name = "tracing-attributes" 1761 | version = "0.1.23" 1762 | source = "registry+https://github.com/rust-lang/crates.io-index" 1763 | checksum = "4017f8f45139870ca7e672686113917c71c7a6e02d4924eda67186083c03081a" 1764 | dependencies = [ 1765 | "proc-macro2", 1766 | "quote", 1767 | "syn 1.0.107", 1768 | ] 1769 | 1770 | [[package]] 1771 | name = "tracing-core" 1772 | version = "0.1.30" 1773 | source = "registry+https://github.com/rust-lang/crates.io-index" 1774 | checksum = "24eb03ba0eab1fd845050058ce5e616558e8f8d8fca633e6b163fe25c797213a" 1775 | dependencies = [ 1776 | "once_cell", 1777 | "valuable", 1778 | ] 1779 | 1780 | [[package]] 1781 | name = "tracing-serde" 1782 | version = "0.1.3" 1783 | source = "registry+https://github.com/rust-lang/crates.io-index" 1784 | checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" 1785 | dependencies = [ 1786 | "serde", 1787 | "tracing-core", 1788 | ] 1789 | 1790 | [[package]] 1791 | name = "tracing-subscriber" 1792 | version = "0.3.18" 1793 | source = "registry+https://github.com/rust-lang/crates.io-index" 1794 | checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" 1795 | dependencies = [ 1796 | "matchers", 1797 | "once_cell", 1798 | "regex", 1799 | "serde", 1800 | "serde_json", 1801 | "sharded-slab", 1802 | "thread_local", 1803 | "tracing", 1804 | "tracing-core", 1805 | "tracing-serde", 1806 | ] 1807 | 1808 | [[package]] 1809 | name = "try-lock" 1810 | version = "0.2.4" 1811 | source = "registry+https://github.com/rust-lang/crates.io-index" 1812 | checksum = "3528ecfd12c466c6f163363caf2d02a71161dd5e1cc6ae7b34207ea2d42d81ed" 1813 | 1814 | [[package]] 1815 | name = "typenum" 1816 | version = "1.16.0" 1817 | source = "registry+https://github.com/rust-lang/crates.io-index" 1818 | checksum = "497961ef93d974e23eb6f433eb5fe1b7930b659f06d12dec6fc44a8f554c0bba" 1819 | 1820 | [[package]] 1821 | name = "unicode-bidi" 1822 | version = "0.3.9" 1823 | source = "registry+https://github.com/rust-lang/crates.io-index" 1824 | checksum = "0046be40136ef78dc325e0edefccf84ccddacd0afcc1ca54103fa3c61bbdab1d" 1825 | 1826 | [[package]] 1827 | name = "unicode-ident" 1828 | version = "1.0.6" 1829 | source = "registry+https://github.com/rust-lang/crates.io-index" 1830 | checksum = "84a22b9f218b40614adcb3f4ff08b703773ad44fa9423e4e0d346d5db86e4ebc" 1831 | 1832 | [[package]] 1833 | name = "unicode-normalization" 1834 | version = "0.1.22" 1835 | source = "registry+https://github.com/rust-lang/crates.io-index" 1836 | checksum = "5c5713f0fc4b5db668a2ac63cdb7bb4469d8c9fed047b1d0292cc7b0ce2ba921" 1837 | dependencies = [ 1838 | "tinyvec", 1839 | ] 1840 | 1841 | [[package]] 1842 | name = "unicode-width" 1843 | version = "0.1.10" 1844 | source = "registry+https://github.com/rust-lang/crates.io-index" 1845 | checksum = "c0edd1e5b14653f783770bce4a4dabb4a5108a5370a5f5d8cfe8710c361f6c8b" 1846 | 1847 | [[package]] 1848 | name = "untrusted" 1849 | version = "0.7.1" 1850 | source = "registry+https://github.com/rust-lang/crates.io-index" 1851 | checksum = "a156c684c91ea7d62626509bce3cb4e1d9ed5c4d978f7b4352658f96a4c26b4a" 1852 | 1853 | [[package]] 1854 | name = "untrusted" 1855 | version = "0.9.0" 1856 | source = "registry+https://github.com/rust-lang/crates.io-index" 1857 | checksum = "8ecb6da28b8a351d773b68d5825ac39017e680750f980f3a1a85cd8dd28a47c1" 1858 | 1859 | [[package]] 1860 | name = "url" 1861 | version = "2.3.1" 1862 | source = "registry+https://github.com/rust-lang/crates.io-index" 1863 | checksum = "0d68c799ae75762b8c3fe375feb6600ef5602c883c5d21eb51c09f22b83c4643" 1864 | dependencies = [ 1865 | "form_urlencoded", 1866 | "idna", 1867 | "percent-encoding", 1868 | ] 1869 | 1870 | [[package]] 1871 | name = "urlencoding" 1872 | version = "2.1.2" 1873 | source = "registry+https://github.com/rust-lang/crates.io-index" 1874 | checksum = "e8db7427f936968176eaa7cdf81b7f98b980b18495ec28f1b5791ac3bfe3eea9" 1875 | 1876 | [[package]] 1877 | name = "uuid" 1878 | version = "1.8.0" 1879 | source = "registry+https://github.com/rust-lang/crates.io-index" 1880 | checksum = "a183cf7feeba97b4dd1c0d46788634f6221d87fa961b305bed08c851829efcc0" 1881 | 1882 | [[package]] 1883 | name = "valuable" 1884 | version = "0.1.0" 1885 | source = "registry+https://github.com/rust-lang/crates.io-index" 1886 | checksum = "830b7e5d4d90034032940e4ace0d9a9a057e7a45cd94e6c007832e39edb82f6d" 1887 | 1888 | [[package]] 1889 | name = "version_check" 1890 | version = "0.9.4" 1891 | source = "registry+https://github.com/rust-lang/crates.io-index" 1892 | checksum = "49874b5167b65d7193b8aba1567f5c7d93d001cafc34600cee003eda787e483f" 1893 | 1894 | [[package]] 1895 | name = "vsimd" 1896 | version = "0.8.0" 1897 | source = "registry+https://github.com/rust-lang/crates.io-index" 1898 | checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" 1899 | 1900 | [[package]] 1901 | name = "want" 1902 | version = "0.3.0" 1903 | source = "registry+https://github.com/rust-lang/crates.io-index" 1904 | checksum = "1ce8a968cb1cd110d136ff8b819a556d6fb6d919363c61534f6860c7eb172ba0" 1905 | dependencies = [ 1906 | "log", 1907 | "try-lock", 1908 | ] 1909 | 1910 | [[package]] 1911 | name = "wasi" 1912 | version = "0.10.0+wasi-snapshot-preview1" 1913 | source = "registry+https://github.com/rust-lang/crates.io-index" 1914 | checksum = "1a143597ca7c7793eff794def352d41792a93c481eb1042423ff7ff72ba2c31f" 1915 | 1916 | [[package]] 1917 | name = "wasi" 1918 | version = "0.11.0+wasi-snapshot-preview1" 1919 | source = "registry+https://github.com/rust-lang/crates.io-index" 1920 | checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423" 1921 | 1922 | [[package]] 1923 | name = "wasm-bindgen" 1924 | version = "0.2.83" 1925 | source = "registry+https://github.com/rust-lang/crates.io-index" 1926 | checksum = "eaf9f5aceeec8be17c128b2e93e031fb8a4d469bb9c4ae2d7dc1888b26887268" 1927 | dependencies = [ 1928 | "cfg-if", 1929 | "wasm-bindgen-macro", 1930 | ] 1931 | 1932 | [[package]] 1933 | name = "wasm-bindgen-backend" 1934 | version = "0.2.83" 1935 | source = "registry+https://github.com/rust-lang/crates.io-index" 1936 | checksum = "4c8ffb332579b0557b52d268b91feab8df3615f265d5270fec2a8c95b17c1142" 1937 | dependencies = [ 1938 | "bumpalo", 1939 | "log", 1940 | "once_cell", 1941 | "proc-macro2", 1942 | "quote", 1943 | "syn 1.0.107", 1944 | "wasm-bindgen-shared", 1945 | ] 1946 | 1947 | [[package]] 1948 | name = "wasm-bindgen-macro" 1949 | version = "0.2.83" 1950 | source = "registry+https://github.com/rust-lang/crates.io-index" 1951 | checksum = "052be0f94026e6cbc75cdefc9bae13fd6052cdcaf532fa6c45e7ae33a1e6c810" 1952 | dependencies = [ 1953 | "quote", 1954 | "wasm-bindgen-macro-support", 1955 | ] 1956 | 1957 | [[package]] 1958 | name = "wasm-bindgen-macro-support" 1959 | version = "0.2.83" 1960 | source = "registry+https://github.com/rust-lang/crates.io-index" 1961 | checksum = "07bc0c051dc5f23e307b13285f9d75df86bfdf816c5721e573dec1f9b8aa193c" 1962 | dependencies = [ 1963 | "proc-macro2", 1964 | "quote", 1965 | "syn 1.0.107", 1966 | "wasm-bindgen-backend", 1967 | "wasm-bindgen-shared", 1968 | ] 1969 | 1970 | [[package]] 1971 | name = "wasm-bindgen-shared" 1972 | version = "0.2.83" 1973 | source = "registry+https://github.com/rust-lang/crates.io-index" 1974 | checksum = "1c38c045535d93ec4f0b4defec448e4291638ee608530863b1e2ba115d4fff7f" 1975 | 1976 | [[package]] 1977 | name = "web-sys" 1978 | version = "0.3.60" 1979 | source = "registry+https://github.com/rust-lang/crates.io-index" 1980 | checksum = "bcda906d8be16e728fd5adc5b729afad4e444e106ab28cd1c7256e54fa61510f" 1981 | dependencies = [ 1982 | "js-sys", 1983 | "wasm-bindgen", 1984 | ] 1985 | 1986 | [[package]] 1987 | name = "winapi" 1988 | version = "0.3.9" 1989 | source = "registry+https://github.com/rust-lang/crates.io-index" 1990 | checksum = "5c839a674fcd7a98952e593242ea400abe93992746761e38641405d28b00f419" 1991 | dependencies = [ 1992 | "winapi-i686-pc-windows-gnu", 1993 | "winapi-x86_64-pc-windows-gnu", 1994 | ] 1995 | 1996 | [[package]] 1997 | name = "winapi-i686-pc-windows-gnu" 1998 | version = "0.4.0" 1999 | source = "registry+https://github.com/rust-lang/crates.io-index" 2000 | checksum = "ac3b87c63620426dd9b991e5ce0329eff545bccbbb34f3be09ff6fb6ab51b7b6" 2001 | 2002 | [[package]] 2003 | name = "winapi-util" 2004 | version = "0.1.5" 2005 | source = "registry+https://github.com/rust-lang/crates.io-index" 2006 | checksum = "70ec6ce85bb158151cae5e5c87f95a8e97d2c0c4b001223f33a334e3ce5de178" 2007 | dependencies = [ 2008 | "winapi", 2009 | ] 2010 | 2011 | [[package]] 2012 | name = "winapi-x86_64-pc-windows-gnu" 2013 | version = "0.4.0" 2014 | source = "registry+https://github.com/rust-lang/crates.io-index" 2015 | checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" 2016 | 2017 | [[package]] 2018 | name = "windows-sys" 2019 | version = "0.42.0" 2020 | source = "registry+https://github.com/rust-lang/crates.io-index" 2021 | checksum = "5a3e1820f08b8513f676f7ab6c1f99ff312fb97b553d30ff4dd86f9f15728aa7" 2022 | dependencies = [ 2023 | "windows_aarch64_gnullvm 0.42.1", 2024 | "windows_aarch64_msvc 0.42.1", 2025 | "windows_i686_gnu 0.42.1", 2026 | "windows_i686_msvc 0.42.1", 2027 | "windows_x86_64_gnu 0.42.1", 2028 | "windows_x86_64_gnullvm 0.42.1", 2029 | "windows_x86_64_msvc 0.42.1", 2030 | ] 2031 | 2032 | [[package]] 2033 | name = "windows-sys" 2034 | version = "0.48.0" 2035 | source = "registry+https://github.com/rust-lang/crates.io-index" 2036 | checksum = "677d2418bec65e3338edb076e806bc1ec15693c5d0104683f2efe857f61056a9" 2037 | dependencies = [ 2038 | "windows-targets 0.48.5", 2039 | ] 2040 | 2041 | [[package]] 2042 | name = "windows-sys" 2043 | version = "0.52.0" 2044 | source = "registry+https://github.com/rust-lang/crates.io-index" 2045 | checksum = "282be5f36a8ce781fad8c8ae18fa3f9beff57ec1b52cb3de0789201425d9a33d" 2046 | dependencies = [ 2047 | "windows-targets 0.52.5", 2048 | ] 2049 | 2050 | [[package]] 2051 | name = "windows-targets" 2052 | version = "0.48.5" 2053 | source = "registry+https://github.com/rust-lang/crates.io-index" 2054 | checksum = "9a2fa6e2155d7247be68c096456083145c183cbbbc2764150dda45a87197940c" 2055 | dependencies = [ 2056 | "windows_aarch64_gnullvm 0.48.5", 2057 | "windows_aarch64_msvc 0.48.5", 2058 | "windows_i686_gnu 0.48.5", 2059 | "windows_i686_msvc 0.48.5", 2060 | "windows_x86_64_gnu 0.48.5", 2061 | "windows_x86_64_gnullvm 0.48.5", 2062 | "windows_x86_64_msvc 0.48.5", 2063 | ] 2064 | 2065 | [[package]] 2066 | name = "windows-targets" 2067 | version = "0.52.5" 2068 | source = "registry+https://github.com/rust-lang/crates.io-index" 2069 | checksum = "6f0713a46559409d202e70e28227288446bf7841d3211583a4b53e3f6d96e7eb" 2070 | dependencies = [ 2071 | "windows_aarch64_gnullvm 0.52.5", 2072 | "windows_aarch64_msvc 0.52.5", 2073 | "windows_i686_gnu 0.52.5", 2074 | "windows_i686_gnullvm", 2075 | "windows_i686_msvc 0.52.5", 2076 | "windows_x86_64_gnu 0.52.5", 2077 | "windows_x86_64_gnullvm 0.52.5", 2078 | "windows_x86_64_msvc 0.52.5", 2079 | ] 2080 | 2081 | [[package]] 2082 | name = "windows_aarch64_gnullvm" 2083 | version = "0.42.1" 2084 | source = "registry+https://github.com/rust-lang/crates.io-index" 2085 | checksum = "8c9864e83243fdec7fc9c5444389dcbbfd258f745e7853198f365e3c4968a608" 2086 | 2087 | [[package]] 2088 | name = "windows_aarch64_gnullvm" 2089 | version = "0.48.5" 2090 | source = "registry+https://github.com/rust-lang/crates.io-index" 2091 | checksum = "2b38e32f0abccf9987a4e3079dfb67dcd799fb61361e53e2882c3cbaf0d905d8" 2092 | 2093 | [[package]] 2094 | name = "windows_aarch64_gnullvm" 2095 | version = "0.52.5" 2096 | source = "registry+https://github.com/rust-lang/crates.io-index" 2097 | checksum = "7088eed71e8b8dda258ecc8bac5fb1153c5cffaf2578fc8ff5d61e23578d3263" 2098 | 2099 | [[package]] 2100 | name = "windows_aarch64_msvc" 2101 | version = "0.42.1" 2102 | source = "registry+https://github.com/rust-lang/crates.io-index" 2103 | checksum = "4c8b1b673ffc16c47a9ff48570a9d85e25d265735c503681332589af6253c6c7" 2104 | 2105 | [[package]] 2106 | name = "windows_aarch64_msvc" 2107 | version = "0.48.5" 2108 | source = "registry+https://github.com/rust-lang/crates.io-index" 2109 | checksum = "dc35310971f3b2dbbf3f0690a219f40e2d9afcf64f9ab7cc1be722937c26b4bc" 2110 | 2111 | [[package]] 2112 | name = "windows_aarch64_msvc" 2113 | version = "0.52.5" 2114 | source = "registry+https://github.com/rust-lang/crates.io-index" 2115 | checksum = "9985fd1504e250c615ca5f281c3f7a6da76213ebd5ccc9561496568a2752afb6" 2116 | 2117 | [[package]] 2118 | name = "windows_i686_gnu" 2119 | version = "0.42.1" 2120 | source = "registry+https://github.com/rust-lang/crates.io-index" 2121 | checksum = "de3887528ad530ba7bdbb1faa8275ec7a1155a45ffa57c37993960277145d640" 2122 | 2123 | [[package]] 2124 | name = "windows_i686_gnu" 2125 | version = "0.48.5" 2126 | source = "registry+https://github.com/rust-lang/crates.io-index" 2127 | checksum = "a75915e7def60c94dcef72200b9a8e58e5091744960da64ec734a6c6e9b3743e" 2128 | 2129 | [[package]] 2130 | name = "windows_i686_gnu" 2131 | version = "0.52.5" 2132 | source = "registry+https://github.com/rust-lang/crates.io-index" 2133 | checksum = "88ba073cf16d5372720ec942a8ccbf61626074c6d4dd2e745299726ce8b89670" 2134 | 2135 | [[package]] 2136 | name = "windows_i686_gnullvm" 2137 | version = "0.52.5" 2138 | source = "registry+https://github.com/rust-lang/crates.io-index" 2139 | checksum = "87f4261229030a858f36b459e748ae97545d6f1ec60e5e0d6a3d32e0dc232ee9" 2140 | 2141 | [[package]] 2142 | name = "windows_i686_msvc" 2143 | version = "0.42.1" 2144 | source = "registry+https://github.com/rust-lang/crates.io-index" 2145 | checksum = "bf4d1122317eddd6ff351aa852118a2418ad4214e6613a50e0191f7004372605" 2146 | 2147 | [[package]] 2148 | name = "windows_i686_msvc" 2149 | version = "0.48.5" 2150 | source = "registry+https://github.com/rust-lang/crates.io-index" 2151 | checksum = "8f55c233f70c4b27f66c523580f78f1004e8b5a8b659e05a4eb49d4166cca406" 2152 | 2153 | [[package]] 2154 | name = "windows_i686_msvc" 2155 | version = "0.52.5" 2156 | source = "registry+https://github.com/rust-lang/crates.io-index" 2157 | checksum = "db3c2bf3d13d5b658be73463284eaf12830ac9a26a90c717b7f771dfe97487bf" 2158 | 2159 | [[package]] 2160 | name = "windows_x86_64_gnu" 2161 | version = "0.42.1" 2162 | source = "registry+https://github.com/rust-lang/crates.io-index" 2163 | checksum = "c1040f221285e17ebccbc2591ffdc2d44ee1f9186324dd3e84e99ac68d699c45" 2164 | 2165 | [[package]] 2166 | name = "windows_x86_64_gnu" 2167 | version = "0.48.5" 2168 | source = "registry+https://github.com/rust-lang/crates.io-index" 2169 | checksum = "53d40abd2583d23e4718fddf1ebec84dbff8381c07cae67ff7768bbf19c6718e" 2170 | 2171 | [[package]] 2172 | name = "windows_x86_64_gnu" 2173 | version = "0.52.5" 2174 | source = "registry+https://github.com/rust-lang/crates.io-index" 2175 | checksum = "4e4246f76bdeff09eb48875a0fd3e2af6aada79d409d33011886d3e1581517d9" 2176 | 2177 | [[package]] 2178 | name = "windows_x86_64_gnullvm" 2179 | version = "0.42.1" 2180 | source = "registry+https://github.com/rust-lang/crates.io-index" 2181 | checksum = "628bfdf232daa22b0d64fdb62b09fcc36bb01f05a3939e20ab73aaf9470d0463" 2182 | 2183 | [[package]] 2184 | name = "windows_x86_64_gnullvm" 2185 | version = "0.48.5" 2186 | source = "registry+https://github.com/rust-lang/crates.io-index" 2187 | checksum = "0b7b52767868a23d5bab768e390dc5f5c55825b6d30b86c844ff2dc7414044cc" 2188 | 2189 | [[package]] 2190 | name = "windows_x86_64_gnullvm" 2191 | version = "0.52.5" 2192 | source = "registry+https://github.com/rust-lang/crates.io-index" 2193 | checksum = "852298e482cd67c356ddd9570386e2862b5673c85bd5f88df9ab6802b334c596" 2194 | 2195 | [[package]] 2196 | name = "windows_x86_64_msvc" 2197 | version = "0.42.1" 2198 | source = "registry+https://github.com/rust-lang/crates.io-index" 2199 | checksum = "447660ad36a13288b1db4d4248e857b510e8c3a225c822ba4fb748c0aafecffd" 2200 | 2201 | [[package]] 2202 | name = "windows_x86_64_msvc" 2203 | version = "0.48.5" 2204 | source = "registry+https://github.com/rust-lang/crates.io-index" 2205 | checksum = "ed94fce61571a4006852b7389a063ab983c02eb1bb37b47f8272ce92d06d9538" 2206 | 2207 | [[package]] 2208 | name = "windows_x86_64_msvc" 2209 | version = "0.52.5" 2210 | source = "registry+https://github.com/rust-lang/crates.io-index" 2211 | checksum = "bec47e5bfd1bff0eeaf6d8b485cc1074891a197ab4225d504cb7a1ab88b02bf0" 2212 | 2213 | [[package]] 2214 | name = "xmlparser" 2215 | version = "0.13.5" 2216 | source = "registry+https://github.com/rust-lang/crates.io-index" 2217 | checksum = "4d25c75bf9ea12c4040a97f829154768bbbce366287e2dc044af160cd79a13fd" 2218 | 2219 | [[package]] 2220 | name = "zeroize" 2221 | version = "1.5.7" 2222 | source = "registry+https://github.com/rust-lang/crates.io-index" 2223 | checksum = "c394b5bd0c6f669e7275d9c20aa90ae064cb22e75a1cad54e1b34088034b149f" 2224 | --------------------------------------------------------------------------------