Skip to content

SecretConfig

Bases: BaseModel, NameValidationMixin

Configuration model for AWS Secrets Manager secret creation.

Defines the structure and validation rules for creating secrets, with special handling for database secrets that require specific keys.

This model supports both database secrets (with predefined key structures) and general-purpose secrets with custom key-value pairs. Database secrets automatically follow AWS RDS integration patterns, while general secrets allow flexible data storage.

Attributes:

Name Type Description
is_db_secret bool

Flag indicating if this is a database credential secret

is_shareable bool

Enable cross-account secret sharing for multi-environment access

secret_data Dict[str, Union[str, bool]]

Key-value pairs containing the actual secret information

secret_base_name str

Base identifier for the secret following naming conventions

Source code in mare_aws_common_lib/models/secret_config.py
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
class SecretConfig(BaseModel, NameValidationMixin):
    """Configuration model for AWS Secrets Manager secret creation.

    Defines the structure and validation rules for creating secrets,
    with special handling for database secrets that require specific keys.

    This model supports both database secrets (with predefined key structures) and
    general-purpose secrets with custom key-value pairs. Database secrets automatically
    follow AWS RDS integration patterns, while general secrets allow flexible data storage.

    Attributes:
        is_db_secret: Flag indicating if this is a database credential secret
        is_shareable: Enable cross-account secret sharing for multi-environment access
        secret_data: Key-value pairs containing the actual secret information
        secret_base_name: Base identifier for the secret following naming conventions
    """

    model_config = ConfigDict(extra="forbid")

    is_db_secret: bool = Field(..., description="Whether this config contains a DB secret")
    is_shareable: bool = Field(default=False, description="Whether the secret is shareable between different accounts")
    secret_data: Dict[str, Union[str, bool]] = Field(..., description="Details (keys and values) for the secret")
    secret_base_name: str = Field(..., min_length=1, description="Base name for the secret")
    use_snc_key: bool = Field(default=False, description="Whether to use the SNC key for encryption")
    snc_key_from_foundation: bool = Field(default=False, description="Whether the SNC key is provided by the foundation")

    @field_validator("secret_base_name")
    @classmethod
    def validate_secret_name(cls, value: str) -> str:
        """Validate the secret base name.

        Applies validation rules to secret naming to ensure the 
        name meets AWS requirements and organizational standards.

        Args:
            value: Raw secret base name from configuration

        Returns:
            Validated secret base name

        Raises:
            ValueError: If the secret name fails validation rules
        """
        return cls.validate_name(value)

    @model_validator(mode="after")
    def validate_and_normalize_iam_role(self) -> 'SecretConfig':
        """Validate and normalize the IAM role setting for database secrets.

        Converts string "true"/"false" values to boolean and sets default
        to False if missing. Only applies to database secrets.

        Returns:
            Self with normalized secret_data

        Raises:
            ValueError: If the IAM role value is invalid
        """
        if self.is_db_secret:
            key = "db_app_user_is_iam_role"
            raw_val = self.secret_data.get(key)

            # Default if missing
            if raw_val is None:
                self.secret_data[key] = False
                return self

            # String case
            if isinstance(raw_val, str):
                raw_val_lc = raw_val.strip().lower()
                if raw_val_lc not in {"true", "false"}:
                    raise ValueError(
                        f"Invalid value for '{key}': '{raw_val}'. Must be 'true' or 'false'"
                    )
                self.secret_data[key] = raw_val_lc == "true"

            # Boolean case
            elif isinstance(raw_val, bool):
                pass  # Already fine

            else:
                raise ValueError(
                    f"Invalid type for '{key}': {type(raw_val).__name__}. "
                    "Must be string 'true'/'false' or boolean"
                )

        return self


    @model_validator(mode="after")
    def check_keys(self) -> 'SecretConfig':
        """Validate secret data keys and set defaults for database secrets.

        For database secrets, ensures required keys are present, sets defaults
        for optional keys, validates boolean string values, and ensures no 
        forbidden keys are included.

        Returns:
            Self after validation

        Raises:
            ValueError: If required DB keys are missing, forbidden keys are present,
                    or boolean values are invalid
        """
        if self.is_db_secret:
            allowed_keys = {"db_username", "db_app_username", "db_app_user_is_iam_role", "schema"}
            actual_keys = set(self.secret_data.keys())
            if "db_username" not in actual_keys:
                raise ValueError("Missing required required key 'db_username' in 'secret_data'")

            not_allowed_keys = actual_keys - allowed_keys
            if not_allowed_keys:
                raise ValueError(f"There are forbidden keys in 'secret_data'. Allowed keys are: {allowed_keys}")

        return self

    @model_validator(mode='after')
    def validate_snc_key_dependencies(self) -> 'SecretConfig':
        """Validate SNC key configuration dependencies.

        Ensures that snc_key_from_foundation can only be True when use_snc_key
        is also True, maintaining logical consistency in SNC key usage configuration.
        Foundation-provided SNC keys require the general SNC key usage to be enabled.

        Returns:
            Self after validation

        Raises:
            ValueError: If snc_key_from_foundation is True while use_snc_key is False
        """
        if self.snc_key_from_foundation and not self.use_snc_key:
            raise ValueError(
                "snc_key_from_foundation cannot be True when use_snc_key is False. "
                "To use a foundation SNC key, use_snc_key must be enabled."
            )
        return self

check_keys()

Validate secret data keys and set defaults for database secrets.

For database secrets, ensures required keys are present, sets defaults for optional keys, validates boolean string values, and ensures no forbidden keys are included.

Returns:

Type Description
SecretConfig

Self after validation

Raises:

Type Description
ValueError

If required DB keys are missing, forbidden keys are present, or boolean values are invalid

Source code in mare_aws_common_lib/models/secret_config.py
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
@model_validator(mode="after")
def check_keys(self) -> 'SecretConfig':
    """Validate secret data keys and set defaults for database secrets.

    For database secrets, ensures required keys are present, sets defaults
    for optional keys, validates boolean string values, and ensures no 
    forbidden keys are included.

    Returns:
        Self after validation

    Raises:
        ValueError: If required DB keys are missing, forbidden keys are present,
                or boolean values are invalid
    """
    if self.is_db_secret:
        allowed_keys = {"db_username", "db_app_username", "db_app_user_is_iam_role", "schema"}
        actual_keys = set(self.secret_data.keys())
        if "db_username" not in actual_keys:
            raise ValueError("Missing required required key 'db_username' in 'secret_data'")

        not_allowed_keys = actual_keys - allowed_keys
        if not_allowed_keys:
            raise ValueError(f"There are forbidden keys in 'secret_data'. Allowed keys are: {allowed_keys}")

    return self

validate_and_normalize_iam_role()

Validate and normalize the IAM role setting for database secrets.

Converts string "true"/"false" values to boolean and sets default to False if missing. Only applies to database secrets.

Returns:

Type Description
SecretConfig

Self with normalized secret_data

Raises:

Type Description
ValueError

If the IAM role value is invalid

Source code in mare_aws_common_lib/models/secret_config.py
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
@model_validator(mode="after")
def validate_and_normalize_iam_role(self) -> 'SecretConfig':
    """Validate and normalize the IAM role setting for database secrets.

    Converts string "true"/"false" values to boolean and sets default
    to False if missing. Only applies to database secrets.

    Returns:
        Self with normalized secret_data

    Raises:
        ValueError: If the IAM role value is invalid
    """
    if self.is_db_secret:
        key = "db_app_user_is_iam_role"
        raw_val = self.secret_data.get(key)

        # Default if missing
        if raw_val is None:
            self.secret_data[key] = False
            return self

        # String case
        if isinstance(raw_val, str):
            raw_val_lc = raw_val.strip().lower()
            if raw_val_lc not in {"true", "false"}:
                raise ValueError(
                    f"Invalid value for '{key}': '{raw_val}'. Must be 'true' or 'false'"
                )
            self.secret_data[key] = raw_val_lc == "true"

        # Boolean case
        elif isinstance(raw_val, bool):
            pass  # Already fine

        else:
            raise ValueError(
                f"Invalid type for '{key}': {type(raw_val).__name__}. "
                "Must be string 'true'/'false' or boolean"
            )

    return self

validate_secret_name(value) classmethod

Validate the secret base name.

Applies validation rules to secret naming to ensure the name meets AWS requirements and organizational standards.

Parameters:

Name Type Description Default
value str

Raw secret base name from configuration

required

Returns:

Type Description
str

Validated secret base name

Raises:

Type Description
ValueError

If the secret name fails validation rules

Source code in mare_aws_common_lib/models/secret_config.py
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
@field_validator("secret_base_name")
@classmethod
def validate_secret_name(cls, value: str) -> str:
    """Validate the secret base name.

    Applies validation rules to secret naming to ensure the 
    name meets AWS requirements and organizational standards.

    Args:
        value: Raw secret base name from configuration

    Returns:
        Validated secret base name

    Raises:
        ValueError: If the secret name fails validation rules
    """
    return cls.validate_name(value)

validate_snc_key_dependencies()

Validate SNC key configuration dependencies.

Ensures that snc_key_from_foundation can only be True when use_snc_key is also True, maintaining logical consistency in SNC key usage configuration. Foundation-provided SNC keys require the general SNC key usage to be enabled.

Returns:

Type Description
SecretConfig

Self after validation

Raises:

Type Description
ValueError

If snc_key_from_foundation is True while use_snc_key is False

Source code in mare_aws_common_lib/models/secret_config.py
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
@model_validator(mode='after')
def validate_snc_key_dependencies(self) -> 'SecretConfig':
    """Validate SNC key configuration dependencies.

    Ensures that snc_key_from_foundation can only be True when use_snc_key
    is also True, maintaining logical consistency in SNC key usage configuration.
    Foundation-provided SNC keys require the general SNC key usage to be enabled.

    Returns:
        Self after validation

    Raises:
        ValueError: If snc_key_from_foundation is True while use_snc_key is False
    """
    if self.snc_key_from_foundation and not self.use_snc_key:
        raise ValueError(
            "snc_key_from_foundation cannot be True when use_snc_key is False. "
            "To use a foundation SNC key, use_snc_key must be enabled."
        )
    return self
Example
from mare_aws_common_lib.models import SecretConfig

config = SecretConfig(
    secret_base_name="my-app-db",
    is_db_secret=True,
    is_shareable=False,
    secret_data={
        "db_username": "admin",
        "db_app_username": "app_user"
    }
)