momento_functions_host/aws/
auth.rs

1//! Host interfaces for working with AWS credentials
2
3use momento_functions_wit::host::momento::host::aws_auth;
4use momento_functions_wit::host::momento::host::aws_auth::AuthError;
5
6/// Reads AWS credentials from the environment variables
7/// `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` at build time.
8///
9/// This is not the best way to encode AWS access, but it is included as a simple
10/// way to get started with calling AWS.
11///
12/// The credentials must be set in the environment at build time, something like
13/// ```bash
14/// AWS_ACCESS_KEY_ID=$DEVELOPER_KEY_ID \
15/// AWS_SECRET_ACCESS_KEY=$DEVELOPER_SECRET_KEY \
16/// cargo build --target wasm32-wasip2 --release
17/// ```
18///
19/// If your build environment does not have the variables set, the key and secret
20/// will be `UNSET`. It is highly unlikely that this will work for calling AWS.
21///
22/// **Examples:**
23/// ________
24/// Read from the normal environment variables
25/// ```rust
26/// # use momento_functions_host::build_environment_aws_credentials;
27/// let credentials = build_environment_aws_credentials!();
28/// ```
29/// ________
30/// Read from foo_AWS_ACCESS_KEY_ID and foo_AWS_SECRET_ACCESS_KEY
31/// ```rust
32/// # use momento_functions_host::build_environment_aws_credentials;
33/// let credentials = build_environment_aws_credentials!("foo_");
34/// ```
35#[macro_export]
36macro_rules! build_environment_aws_credentials {
37    ($prefix:literal) => {
38        momento_functions_host::aws::auth::Credentials::Hardcoded {
39            access_key_id: option_env!(concat!($prefix, "AWS_ACCESS_KEY_ID"))
40                .unwrap_or("UNSET")
41                .to_string(),
42            secret_access_key: option_env!(concat!($prefix, "AWS_SECRET_ACCESS_KEY"))
43                .unwrap_or("UNSET")
44                .to_string(),
45        }
46    };
47    () => {
48        build_environment_aws_credentials!("")
49    };
50}
51
52/// The authorization strategy to use when connecting to AWS services.
53pub enum Credentials {
54    /// Credentials that are hardcoded in the application.
55    /// You should use a different strategy if you can.
56    ///
57    /// Compiled wasm archives are irretrievable from Momento. The only way to leak
58    /// hardcoded credentials after uploading to Momento is for you to write code to
59    /// exfiltrate them.
60    Hardcoded {
61        /// The AWS access key ID for the IAM user you wish to use
62        access_key_id: String,
63        /// The AWS secret access key for the IAM user you wish to use
64        secret_access_key: String,
65    },
66}
67
68/// A configured AWS credentials provider. This can be used to connect to AWS services.
69pub struct AwsCredentialsProvider {
70    resource: aws_auth::CredentialsProvider,
71}
72
73impl AwsCredentialsProvider {
74    /// The credentials to use when connecting to AWS services.
75    ///
76    /// **Examples:**
77    /// ```rust,no_run
78    /// # // Not run because docs.rs does not run a Momento WIT host environment, of course!
79    /// # // But it does at least compile, to make sure the example is correct.
80    /// # use momento_functions_host::{build_environment_aws_credentials, aws::auth::{AwsCredentialsProvider}};
81    /// let provider = AwsCredentialsProvider::new("us-east-1", build_environment_aws_credentials!());
82    /// ```
83    pub fn new(
84        region: impl AsRef<str>,
85        credentials: Credentials,
86    ) -> Result<AwsCredentialsProvider, AuthError> {
87        let wit_authorization = match credentials {
88            Credentials::Hardcoded {
89                access_key_id,
90                secret_access_key,
91            } => aws_auth::Authorization::Hardcoded(aws_auth::Credentials {
92                access_key_id,
93                secret_access_key,
94            }),
95        };
96
97        let resource = aws_auth::provider(&wit_authorization, region.as_ref())?;
98
99        momento_functions_wit::host::momento::host::aws_ddb::Client::new(&resource);
100
101        Ok(AwsCredentialsProvider { resource })
102    }
103
104    /// Returns the underlying WIT resource.
105    pub(crate) fn resource(&self) -> &aws_auth::CredentialsProvider {
106        &self.resource
107    }
108}