Skip to content

Commit a40db32

Browse files
authored
Merge pull request #10 from phasehq/feat--cross-app-secret-referencing
feat: cross app secret referencing
2 parents 246fe13 + 0c94205 commit a40db32

File tree

3 files changed

+62
-9
lines changed

3 files changed

+62
-9
lines changed

README.md

+7-6
Original file line numberDiff line numberDiff line change
@@ -10,12 +10,13 @@ The Phase Secrets SDK provides a Go package for managing secrets in your applica
1010

1111
### Secret Referencing Syntax
1212

13-
| Reference Syntax | Environment | Path | Secret Key | Description |
14-
|-----------------------------------|------------------|-----------------------------------|------------------------|-------------------------------------------------------------|
15-
| `${KEY}` | Same environment | `/` | KEY | Local reference in the same environment and root path (/). |
16-
| `${staging.DEBUG}` | `staging` | `/` (root of staging environment) | DEBUG | Cross-environment reference to a secret at the root (/). |
17-
| `${prod./frontend/SECRET_KEY}` | `prod` | `/frontend/` | SECRET_KEY | Cross-environment reference to a secret in a specific path. |
18-
| `${/backend/payments/STRIPE_KEY}` | Same environment | `/backend/payments/` | STRIPE_KEY | Local reference with a specified path. |
13+
| Reference Syntax | Application | Environment | Path | Secret Key | Description |
14+
|-------------------------------------------|------------------|------------------|-----------------------------------|------------------------|-------------------------------------------------------------|
15+
| `${KEY}` | Same application | Same environment | `/` | KEY | Local reference in the same environment and root path (/). |
16+
| `${staging.DEBUG}` | Same application | `staging` | `/` (root of staging environment) | DEBUG | Cross-environment reference to a secret at the root (/). |
17+
| `${prod./frontend/SECRET_KEY}` | Same application | `prod` | `/frontend/` | SECRET_KEY | Cross-environment reference to a secret in a specific path. |
18+
| `${/backend/payments/STRIPE_KEY}` | Same application | Same environment | `/backend/payments/` | STRIPE_KEY | Local reference with a specified path. |
19+
| `${backend_api::production./frontend/KEY}` | `backend_api` | `production` | `/frontend/` | KEY | Cross-application reference to a secret in a specific path. |
1920

2021
## Installation
2122

phase/misc/const.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ import (
55
)
66

77
const (
8-
Version = "1.0.2"
8+
Version = "1.0.3"
99
PhVersion = "v1"
1010
PhaseCloudAPIHost = "https://console.phase.dev"
1111
)

phase/phase.go

+54-2
Original file line numberDiff line numberDiff line change
@@ -109,8 +109,53 @@ func Init(serviceToken, host string, debug bool) *Phase {
109109
}
110110
}
111111

112+
// resolveSecretReference parses and resolves a secret reference to its actual value.
113+
//
114+
// The function supports multiple reference formats:
115+
//
116+
// 1. Local Reference (Root Path):
117+
// Syntax: `KEY`
118+
// - Environment: Same as the current environment.
119+
// - Path: Root path (`/`).
120+
// - Secret Key: `KEY`
121+
//
122+
// 2. Local Reference (Specified Path):
123+
// Syntax: `/backend/payments/STRIPE_KEY`
124+
// - Environment: Same as the current environment.
125+
// - Path: Specified path (`/backend/payments/`).
126+
// - Secret Key: `STRIPE_KEY`
127+
//
128+
// 3. Cross-Environment Reference (Root Path):
129+
// Syntax: `staging.DEBUG`
130+
// - Environment: Different environment (e.g., `staging`).
131+
// - Path: Root path (`/`).
132+
// - Secret Key: `DEBUG`
133+
//
134+
// 4. Cross-Environment Reference (Specific Path):
135+
// Syntax: `prod./frontend/SECRET_KEY`
136+
// - Environment: Different environment (e.g., `prod`).
137+
// - Path: Specified path (`/frontend/`).
138+
// - Secret Key: `SECRET_KEY`
139+
//
140+
// 5. Cross-Application Reference:
141+
// Syntax: `backend_api::production./frontend/SECRET_KEY`
142+
// - Application: Different application (e.g., `backend_api`).
143+
// - Environment: Different environment (e.g., `production`).
144+
// - Path: Specified path (`/frontend/`).
145+
// - Secret Key: `SECRET_KEY`
112146
func (p *Phase) resolveSecretReference(ref, currentEnvName string) (string, error) {
113-
var envName, path, keyName string
147+
var appName, envName, path, keyName string
148+
149+
// Default app name is empty, meaning current app
150+
appName = ""
151+
152+
// Check if this is a cross-application reference (contains "::")
153+
if strings.Contains(ref, "::") {
154+
// Split on the first :: to differentiate application from environment/path/key
155+
parts := strings.SplitN(ref, "::", 2)
156+
appName = parts[0]
157+
ref = parts[1] // Update ref to be everything after the app name
158+
}
114159

115160
// Check if the reference starts with an environment name followed by a dot
116161
if strings.Contains(ref, ".") {
@@ -148,7 +193,7 @@ func (p *Phase) resolveSecretReference(ref, currentEnvName string) (string, erro
148193
// Fetch and decrypt the referenced secret
149194
opts := GetSecretOptions{
150195
EnvName: envName,
151-
AppName: "", // AppName is available globally
196+
AppName: appName,
152197
KeyToFind: keyName,
153198
SecretPath: path,
154199
}
@@ -167,6 +212,13 @@ func (p *Phase) resolveSecretReference(ref, currentEnvName string) (string, erro
167212
}
168213

169214
// resolveSecretValue resolves all secret references in a given value string.
215+
//
216+
// This function identifies and resolves all secret references embedded within a string.
217+
// It supports references in the format ${...} where the content inside the braces
218+
// follows the syntax described in resolveSecretReference, including:
219+
// - Local references: ${KEY} or ${/path/to/KEY}
220+
// - Cross-environment references: ${env.KEY} or ${env./path/to/KEY}
221+
// - Cross-application references: ${app::env.KEY} or ${app::env./path/to/KEY}
170222
func (p *Phase) resolveSecretValue(value string, currentEnvName string) (string, error) {
171223
refs := misc.SecretRefRegex.FindAllString(value, -1)
172224
resolvedValue := value

0 commit comments

Comments
 (0)