Skip to content

Commit

Permalink
Implement SSOCredentialsProvider (#189)
Browse files Browse the repository at this point in the history
  • Loading branch information
waahm7 committed May 8, 2023
1 parent 8302e79 commit 9762a1d
Show file tree
Hide file tree
Showing 18 changed files with 4,026 additions and 49 deletions.
4 changes: 4 additions & 0 deletions include/aws/auth/auth.h
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,10 @@ enum aws_auth_errors {
AWS_AUTH_SIGV4A_SIGNATURE_VALIDATION_FAILURE,
AWS_AUTH_CREDENTIALS_PROVIDER_COGNITO_SOURCE_FAILURE,
AWS_AUTH_CREDENTIALS_PROVIDER_DELEGATE_FAILURE,
AWS_AUTH_SSO_TOKEN_PROVIDER_SOURCE_FAILURE,
AWS_AUTH_SSO_TOKEN_INVALID,
AWS_AUTH_SSO_TOKEN_EXPIRED,
AWS_AUTH_CREDENTIALS_PROVIDER_SSO_SOURCE_FAILURE,

AWS_AUTH_ERROR_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_AUTH_PACKAGE_ID)
};
Expand Down
64 changes: 60 additions & 4 deletions include/aws/auth/credentials.h
Original file line number Diff line number Diff line change
Expand Up @@ -90,8 +90,8 @@ struct aws_credentials_provider_environment_options {
};

/**
* Configuration options for a provider that sources credentials from the aws profile and credentials files
* (by default ~/.aws/profile and ~/.aws/credentials)
* Configuration options for a provider that sources credentials from the aws config and credentials files
* (by default ~/.aws/config and ~/.aws/credentials)
*/
struct aws_credentials_provider_profile_options {
struct aws_credentials_provider_shutdown_options shutdown_options;
Expand All @@ -114,7 +114,7 @@ struct aws_credentials_provider_profile_options {
/**
* (Optional)
* Use a cached merged profile collection. A merge collection has both config file
* (~/.aws/profile) and credentials file based profile collection (~/.aws/credentials) using
* (~/.aws/config) and credentials file based profile collection (~/.aws/credentials) using
* `aws_profile_collection_new_from_merge`.
* If this option is provided, `config_file_name_override` and `credentials_file_name_override` will be ignored.
*/
Expand Down Expand Up @@ -355,6 +355,49 @@ struct aws_credentials_provider_sts_web_identity_options {
struct aws_auth_http_system_vtable *function_table;
};

/*
* Configuration for the SSOCredentialsProvider that sends a GetRoleCredentialsRequest to the AWS Single
* Sign-On Service to maintain short-lived sessions to use for authentication.
*
* https://docs.aws.amazon.com/sdkref/latest/guide/feature-sso-credentials.html
*/
struct aws_credentials_provider_sso_options {
struct aws_credentials_provider_shutdown_options shutdown_options;

/*
* Override of what profile to use to source credentials from ('default' by default)
*/
struct aws_byte_cursor profile_name_override;

/*
* Override path to the profile config file (~/.aws/config by default)
*/
struct aws_byte_cursor config_file_name_override;

/**
* (Optional)
* Use a cached config profile collection. You can also pass a merged collection.
* config_file_name_override will be ignored if this option is provided.
*/
struct aws_profile_collection *config_file_cached;

/*
* Connection bootstrap to use for any network connections made while sourcing credentials
* Required.
*/
struct aws_client_bootstrap *bootstrap;

/*
* Client TLS context to use when querying SSO provider.
* Required.
*/
struct aws_tls_ctx *tls_ctx;

/* For mocking, leave NULL otherwise */
struct aws_auth_http_system_vtable *function_table;
aws_io_clock_fn *system_clock_fn;
};

/**
* Configuration options for the STS credentials provider
*/
Expand Down Expand Up @@ -457,7 +500,7 @@ struct aws_credentials_provider_chain_default_options {
/**
* (Optional)
* Use a cached merged profile collection. A merge collection has both config file
* (~/.aws/profile) and credentials file based profile collection (~/.aws/credentials) using
* (~/.aws/config) and credentials file based profile collection (~/.aws/credentials) using
* `aws_profile_collection_new_from_merge`.
* If this option is provided, `config_file_name_override` and `credentials_file_name_override` will be ignored.
*/
Expand Down Expand Up @@ -927,6 +970,19 @@ struct aws_credentials_provider *aws_credentials_provider_new_sts_web_identity(
struct aws_allocator *allocator,
const struct aws_credentials_provider_sts_web_identity_options *options);

/**
* Creates a provider that sources credentials from SSO using a SSOToken.
*
* @param allocator memory allocator to use for all memory allocation
* @param options provider-specific configuration options
*
* @return the newly-constructed credentials provider, or NULL if an error occurred.
*/
AWS_AUTH_API
struct aws_credentials_provider *aws_credentials_provider_new_sso(
struct aws_allocator *allocator,
const struct aws_credentials_provider_sso_options *options);

/*
* Creates a provider that sources credentials from running an external command or process
*
Expand Down
10 changes: 10 additions & 0 deletions include/aws/auth/private/credentials_utils.h
Original file line number Diff line number Diff line change
Expand Up @@ -73,13 +73,15 @@ struct aws_auth_http_system_vtable {
enum aws_parse_credentials_expiration_format {
AWS_PCEF_STRING_ISO_8601_DATE,
AWS_PCEF_NUMBER_UNIX_EPOCH,
AWS_PCEF_NUMBER_UNIX_EPOCH_MS,
};

struct aws_parse_credentials_from_json_doc_options {
const char *access_key_id_name;
const char *secret_access_key_name;
const char *token_name;
const char *expiration_name;
const char *top_level_object_name;
enum aws_parse_credentials_expiration_format expiration_format;
bool token_required;
bool expiration_required;
Expand Down Expand Up @@ -160,6 +162,14 @@ struct aws_credentials *aws_parse_credentials_from_json_document(
AWS_AUTH_API
enum aws_retry_error_type aws_credentials_provider_compute_retry_error_type(int response_code, int error_code);

/*
* Loads an aws config profile collection
*/
AWS_AUTH_API
struct aws_profile_collection *aws_load_profile_collection_from_config_file(
struct aws_allocator *allocator,
struct aws_byte_cursor config_file_name_override);

AWS_EXTERN_C_END

#endif /* AWS_AUTH_CREDENTIALS_PRIVATE_H */
112 changes: 112 additions & 0 deletions include/aws/auth/private/sso_token_providers.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,112 @@
#ifndef AWS_AUTH_TOKEN_PROVIDERS_PRIVATE_H
#define AWS_AUTH_TOKEN_PROVIDERS_PRIVATE_H

/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

#include <aws/auth/auth.h>
#include <aws/auth/credentials.h>

/**
* Configuration options for a provider that sources sso token information from the aws profile (by default
* ~/.aws/config) and token from ~/.aws/sso/cache/<sha1 of start url>.json.
*/
struct aws_token_provider_sso_profile_options {
struct aws_credentials_provider_shutdown_options shutdown_options;

/*
* Override of what profile to use to source credentials from ('default' by default)
*/
struct aws_byte_cursor profile_name_override;

/*
* Override path to the profile config file (~/.aws/config by default)
*/
struct aws_byte_cursor config_file_name_override;

/**
* (Optional)
* Use a cached config profile collection. You can also pass a merged collection.
* config_file_name_override will be ignored if this option is provided.
*/
struct aws_profile_collection *config_file_cached;

/* For mocking, leave NULL otherwise */
aws_io_clock_fn *system_clock_fn;
};

/**
* Configuration options for a provider that sources sso token information from the aws profile (by default
* ~/.aws/config) and token from ~/.aws/sso/cache/<sha1 of session name>.json.
*/
struct aws_token_provider_sso_session_options {
struct aws_credentials_provider_shutdown_options shutdown_options;

/*
* Override of what profile to use to source credentials from ('default' by default)
*/
struct aws_byte_cursor profile_name_override;

/*
* Override path to the profile config file (~/.aws/config by default)
*/
struct aws_byte_cursor config_file_name_override;

/**
* (Optional)
* Use a cached config profile collection. You can also pass a merged collection.
* config_file_name_override will be ignored if this option is provided.
*/
struct aws_profile_collection *config_file_cached;

/*
* Connection bootstrap to use for any network connections made
*/
struct aws_client_bootstrap *bootstrap;

/*
* Client TLS context to use for any network connections made.
*/
struct aws_tls_ctx *tls_ctx;

/* For mocking, leave NULL otherwise */
aws_io_clock_fn *system_clock_fn;
};

AWS_EXTERN_C_BEGIN

/**
* Creates a provider that sources sso token based credentials from key-value profiles loaded from the aws
* config("~/.aws/config" by default) and ~/.aws/sso/cache/<sha1 of start url>.json
* This is the legacy way which doesn't support refreshing credentials.
*
* @param allocator memory allocator to use for all memory allocation
* @param options provider-specific configuration options
*
* @return the newly-constructed credentials provider, or NULL if an error occurred.
*/
AWS_AUTH_API
struct aws_credentials_provider *aws_token_provider_new_sso_profile(
struct aws_allocator *allocator,
const struct aws_token_provider_sso_profile_options *options);

/**
* Creates a provider that sources sso token based credentials from key-value profiles loaded from the aws
* config("~/.aws/config" by default) and ~/.aws/sso/cache/<sha1 of session name>.json
* Note: Token refresh is not currently supported
*
* @param allocator memory allocator to use for all memory allocation
* @param options provider-specific configuration options
*
* @return the newly-constructed credentials provider, or NULL if an error occurred.
*/
AWS_AUTH_API
struct aws_credentials_provider *aws_token_provider_new_sso_session(
struct aws_allocator *allocator,
const struct aws_token_provider_sso_session_options *options);

AWS_EXTERN_C_END

#endif /* AWS_AUTH_TOKEN_PROVIDERS_PRIVATE_H */
58 changes: 58 additions & 0 deletions include/aws/auth/private/sso_token_utils.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,58 @@
#ifndef AWS_AUTH_TOKEN_PRIVATE_H
#define AWS_AUTH_TOKEN_PRIVATE_H

/**
* Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
* SPDX-License-Identifier: Apache-2.0.
*/

#include <aws/auth/auth.h>
#include <aws/common/date_time.h>

/* structure to represent a parsed sso token */
struct aws_sso_token {
struct aws_allocator *allocator;

struct aws_string *access_token;
struct aws_date_time expiration;
};

AWS_EXTERN_C_BEGIN

/* Construct token path which is ~/.aws/sso/cache/<hex encoded sha1 of input>.json */
AWS_AUTH_API
struct aws_string *aws_construct_sso_token_path(struct aws_allocator *allocator, const struct aws_string *input);

AWS_AUTH_API
void aws_sso_token_destroy(struct aws_sso_token *token);

/* Parse `aws_sso_token` from the give file path */
AWS_AUTH_API
struct aws_sso_token *aws_sso_token_new_from_file(struct aws_allocator *allocator, const struct aws_string *file_path);

/**
* Creates a set of AWS credentials based on a token with expiration.
*
* @param allocator memory allocator to use for all memory allocation
* @param token token for the credentials
* @param expiration_timepoint_in_seconds time at which these credentials expire
* @return a new pair of AWS credentials, or NULL
*/
AWS_AUTH_API
struct aws_credentials *aws_credentials_new_token(
struct aws_allocator *allocator,
struct aws_byte_cursor token,
uint64_t expiration_timepoint_in_seconds);

/**
* Get the token from a set of AWS credentials
*
* @param credentials credentials to get the token from
* @return a byte cursor to the token or an empty byte cursor if there is no token
*/
AWS_AUTH_API
struct aws_byte_cursor aws_credentials_get_token(const struct aws_credentials *credentials);

AWS_EXTERN_C_END

#endif /* AWS_AUTH_TOKEN_PRIVATE_H */
12 changes: 12 additions & 0 deletions source/auth.c
Original file line number Diff line number Diff line change
Expand Up @@ -91,6 +91,18 @@ static struct aws_error_info s_errors[] = {
AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_CREDENTIALS_PROVIDER_DELEGATE_FAILURE,
"Valid credentials could not be sourced by the delegate provider"),
AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_SSO_TOKEN_PROVIDER_SOURCE_FAILURE,
"Valid token could not be sourced by the sso token provider"),
AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_SSO_TOKEN_INVALID,
"Token sourced by the sso token provider is invalid."),
AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_SSO_TOKEN_EXPIRED,
"Token sourced by the sso token provider is expired."),
AWS_DEFINE_ERROR_INFO_AUTH(
AWS_AUTH_CREDENTIALS_PROVIDER_SSO_SOURCE_FAILURE,
"Valid credentials could not be sourced by the sso credentials provider"),

};
/* clang-format on */
Expand Down
Loading

0 comments on commit 9762a1d

Please sign in to comment.