1- import re
21from typing import Dict , List
32from .exceptions import EnvironmentNotFoundException
43from .const import SECRET_REF_REGEX
4+ from .phase_io import Phase
55
66"""
77 Secret Referencing Syntax:
88
99 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.
1212
1313 Syntax Patterns:
1414
4040 - Secret Key: `STRIPE_KEY`
4141 - Description: References a secret named `STRIPE_KEY` located at `/backend/payments/` in the current environment.
4242
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+
4351 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.
4553"""
4654
4755
@@ -74,12 +82,13 @@ def resolve_secret_reference(ref: str, secrets_dict: Dict[str, Dict[str, Dict[st
7482 """
7583 Resolves a single secret reference to its actual value by fetching it from the specified environment.
7684
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.
7886 Local references are identified by the absence of a dot '.' in the reference string, implying the current environment.
7987 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.
8089
8190 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.
8392 secrets_dict (Dict[str, Dict[str, Dict[str, str]]]): A dictionary containing known secrets.
8493 phase ('Phase'): An instance of the Phase class to fetch secrets.
8594 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
8897 Returns:
8998 str: The resolved secret value or the original reference if not resolved.
9099 """
100+ original_ref = ref # Store the original reference
101+ app_name = current_application_name
91102 env_name = current_env_name
92103 path = "/" # Default root path
93104 key_name = ref
94105
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+
95111 # Parse the reference to identify environment, path, and secret key.
96112 if "." in ref : # Cross-environment references
97113 parts = ref .split ("." , 1 )
@@ -112,15 +128,15 @@ def resolve_secret_reference(ref: str, secrets_dict: Dict[str, Dict[str, Dict[st
112128 return secrets_dict [env_name ]['/' ][key_name ]
113129
114130 # 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 )
116132 for secret in fetched_secrets :
117133 if secret ["key" ] == key_name :
118134 return secret ["value" ]
119135 except EnvironmentNotFoundException :
120136 pass
121137
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 } }}"
124140
125141
126142def 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