Skip to content

Commit 2238306

Browse files
authored
Merge pull request #21 from phasehq/feat--cross-app-secret-referencing
feat: cross app secret referencing
2 parents c2e7657 + 71d4dbc commit 2238306

File tree

7 files changed

+38
-22
lines changed

7 files changed

+38
-22
lines changed

helm-repo/index.yaml

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ apiVersion: v1
22
entries:
33
phase:
44
- apiVersion: v2
5-
created: "2025-04-01T23:17:57.887487677+05:30"
5+
created: "2025-04-06T14:37:10.153678271+05:30"
66
description: A Helm chart for deploying the Phase Secrets Manager
77
digest: 00fd9171966c7a0efad5992f5ca50d84c34203253b327e859ef6d0df9311e3f6
88
home: https://github.com/phasehq/kubernetes-secrets-operator
@@ -22,10 +22,10 @@ entries:
2222
version: 0.3.0
2323
phase-kubernetes-operator:
2424
- apiVersion: v2
25-
appVersion: 1.2.3
26-
created: "2025-04-01T23:17:57.887872023+05:30"
25+
appVersion: 1.2.4
26+
created: "2025-04-06T14:37:10.153929128+05:30"
2727
description: A Helm chart for deploying the Phase Kubernetes Operator
28-
digest: 93e571ad092af42648a8731de51d6b1a371f5b738a5b6c5a327ca38fa90d45e4
28+
digest: 4ae6e3dd5c7b1b18863aaaf646dbbb2ac6cc64cdc0a0b35b79ade6b3aac19e72
2929
home: https://github.com/phasehq/kubernetes-secrets-operator
3030
icon: https://phase.dev/apple-touch-icon.png
3131
keywords:
@@ -41,6 +41,6 @@ entries:
4141
- https://github.com/phasehq/kubernetes-secrets-operator
4242
type: application
4343
urls:
44-
- phase-kubernetes-operator-1.2.3.tgz
45-
version: 1.2.3
46-
generated: "2025-04-01T23:17:57.886779868+05:30"
44+
- phase-kubernetes-operator-1.2.4.tgz
45+
version: 1.2.4
46+
generated: "2025-04-06T14:37:10.15293167+05:30"
-3.01 KB
Binary file not shown.
3.01 KB
Binary file not shown.

phase-kubernetes-operator/Chart.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ description: A Helm chart for deploying the Phase Kubernetes Operator
55
type: application
66

77
# Version of the chart
8-
version: 1.2.3
8+
version: 1.2.4
99

1010
# Version of the application (operator) that is being deployed
11-
appVersion: "1.2.3"
11+
appVersion: "1.2.4"
1212

1313
# Keywords, maintainers, and source URLs can also be added here
1414
keywords:

requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
1-
cffi==1.15.1
2-
requests==2.31.0
1+
cffi==1.17.1
2+
requests==2.32.0
33
PyNaCl==1.5.0
4-
kopf==1.36.2
4+
kopf==1.37.5
55
kubernetes==28.1.0
66
pytest==7.3.1
77
pyyaml==6.0.1

src/utils/const.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
import os
22
import re
3-
__version__ = "1.2.3"
3+
__version__ = "1.2.4"
44
__ph_version__ = "v1"
55

66
description = "Securely manage application secrets and environment variables with Phase."

src/utils/secret_referencing.py

Lines changed: 25 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,14 @@
1-
import re
21
from typing import Dict, List
32
from exceptions import EnvironmentNotFoundException
43
from utils.const import SECRET_REF_REGEX
4+
from utils.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
@@ -40,8 +40,16 @@
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

126142
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

Comments
 (0)