1
- import re
2
1
from typing import Dict , List
3
2
from .exceptions import EnvironmentNotFoundException
4
3
from .const import SECRET_REF_REGEX
4
+ from .phase_io import Phase
5
5
6
6
"""
7
7
Secret Referencing Syntax:
8
8
9
9
This documentation explains the syntax used for referencing secrets within the configuration.
10
- Secrets can be referenced both locally (within the same environment) and across different environments,
11
- with or without specifying a path.
10
+ Secrets can be referenced locally (within the same environment), across different environments,
11
+ and across different applications, with or without specifying a path.
12
12
13
13
Syntax Patterns:
14
14
40
40
- Secret Key: `STRIPE_KEY`
41
41
- Description: References a secret named `STRIPE_KEY` located at `/backend/payments/` in the current environment.
42
42
43
+ 5. Cross-Application Reference:
44
+ Syntax: `${backend_api::production./frontend/SECRET_KEY}`
45
+ - Application: Different application (e.g., `backend_api`).
46
+ - Environment: Different environment (e.g., `production`).
47
+ - Path: Specifies a path within the environment (`/frontend/`).
48
+ - Secret Key: `SECRET_KEY`
49
+ - Description: References a secret named `SECRET_KEY` located at `/frontend/` in the `production` environment of the `backend_api` application.
50
+
43
51
Note:
44
- The syntax allows for flexible secret management, enabling both straightforward local references and more complex cross-environment references.
52
+ The syntax allows for flexible secret management, enabling local references, cross-environment references, and cross-application references.
45
53
"""
46
54
47
55
@@ -74,12 +82,13 @@ def resolve_secret_reference(ref: str, secrets_dict: Dict[str, Dict[str, Dict[st
74
82
"""
75
83
Resolves a single secret reference to its actual value by fetching it from the specified environment.
76
84
77
- The function supports both local and cross-environment secret references, allowing for flexible secret management.
85
+ The function supports local, cross-environment, and cross-application secret references, allowing for flexible secret management.
78
86
Local references are identified by the absence of a dot '.' in the reference string, implying the current environment.
79
87
Cross-environment references include an environment name, separated by a dot from the rest of the path.
88
+ Cross-application references use '::' to separate the application name from the rest of the reference.
80
89
81
90
Args:
82
- ref (str): The secret reference string, which could be a local or cross-environment reference.
91
+ ref (str): The secret reference string, which could be a local, cross-environment, or cross-application reference.
83
92
secrets_dict (Dict[str, Dict[str, Dict[str, str]]]): A dictionary containing known secrets.
84
93
phase ('Phase'): An instance of the Phase class to fetch secrets.
85
94
current_application_name (str): The name of the current application.
@@ -88,10 +97,17 @@ def resolve_secret_reference(ref: str, secrets_dict: Dict[str, Dict[str, Dict[st
88
97
Returns:
89
98
str: The resolved secret value or the original reference if not resolved.
90
99
"""
100
+ original_ref = ref # Store the original reference
101
+ app_name = current_application_name
91
102
env_name = current_env_name
92
103
path = "/" # Default root path
93
104
key_name = ref
94
105
106
+ # Check if this is a cross-application reference
107
+ if "::" in ref :
108
+ parts = ref .split ("::" , 1 )
109
+ app_name , ref = parts [0 ], parts [1 ]
110
+
95
111
# Parse the reference to identify environment, path, and secret key.
96
112
if "." in ref : # Cross-environment references
97
113
parts = ref .split ("." , 1 )
@@ -112,15 +128,15 @@ def resolve_secret_reference(ref: str, secrets_dict: Dict[str, Dict[str, Dict[st
112
128
return secrets_dict [env_name ]['/' ][key_name ]
113
129
114
130
# If the secret is not found in secrets_dict, try to fetch it from Phase
115
- fetched_secrets = phase .get (env_name = env_name , app_name = current_application_name , keys = [key_name ], path = path )
131
+ fetched_secrets = phase .get (env_name = env_name , app_name = app_name , keys = [key_name ], path = path )
116
132
for secret in fetched_secrets :
117
133
if secret ["key" ] == key_name :
118
134
return secret ["value" ]
119
135
except EnvironmentNotFoundException :
120
136
pass
121
137
122
- # Return the reference as is if not resolved
123
- return f"${{{ ref } }}"
138
+ # Return the original secret value as is if not resolved
139
+ return f"${{{ original_ref } }}"
124
140
125
141
126
142
def resolve_all_secrets (value : str , all_secrets : List [Dict [str , str ]], phase : 'Phase' , current_application_name : str , current_env_name : str ) -> str :
0 commit comments