Skip to content

Commit 9175120

Browse files
authored
chore: remove third credential override syntax (#585)
Signed-off-by: Grant Linville <[email protected]>
1 parent 07b3be6 commit 9175120

File tree

3 files changed

+142
-43
lines changed

3 files changed

+142
-43
lines changed

docs/docs/03-tools/04-credential-tools.md

+11-32
Original file line numberDiff line numberDiff line change
@@ -148,10 +148,6 @@ This is useful when working with credential overrides.
148148

149149
## Credential Overrides (Advanced)
150150

151-
:::note
152-
The syntax for this will change at some point in the future.
153-
:::
154-
155151
You can bypass credential tools and stored credentials by setting the `--credential-override` argument (or the
156152
`GPTSCRIPT_CREDENTIAL_OVERRIDE` environment variable) when running GPTScript. To set up a credential override, you
157153
need to be aware of which environment variables the credential tool sets. You can find this out by running the
@@ -166,41 +162,24 @@ This can be overridden with a credential alias, i.e. `credential: my-cred-tool.g
166162
If the credential has an alias, use it instead of the tool name when you specify an override.
167163
:::
168164

169-
The `--credential-override` argument must be formatted in one of the following three ways:
165+
The `--credential-override` argument must be formatted in one of the following two ways:
170166

171167
#### 1. Key-Value Pairs
172168

173-
`toolA:ENV_VAR_1=value1,ENV_VAR_2=value2;toolB:ENV_VAR_1=value3,ENV_VAR_2=value4`
169+
`toolA:ENV_VAR_1=value1,ENV_VAR_2=value2`
170+
171+
In this example, both `toolA` provides the variables `ENV_VAR_1` and `ENV_VAR_2`.
172+
This will set the environment variables `ENV_VAR_1` and `ENV_VAR_2` to the specific values `value1` and `value2`.
174173

175-
In this example, both `toolA` and `toolB` provide the variables `ENV_VAR_1` and `ENV_VAR_2`.
176-
This will set the environment variables `ENV_VAR_1` and `ENV_VAR_2` to the specific values provided for each tool.
174+
:::info
175+
To override more than one credential, use `;` as a separator. For example, `toolA:ENV_VAR_1=value1;toolB:ENV_VAR_2=value2`.
176+
:::
177177

178178
#### 2. Environment Variables
179179

180-
`toolA:ENV_VAR_1,ENV_VAR_2;toolB:ENV_VAR_3,ENV_VAR_4`
180+
`toolA:ENV_VAR_1,ENV_VAR_2`
181181

182-
In this example, `toolA` provides the variables `ENV_VAR_1` and `ENV_VAR_2`, and `toolB` provides the variables `ENV_VAR_3` and `ENV_VAR_4`.
183-
This will read the values of `ENV_VAR_1` through `ENV_VAR_4` from the current environment and set them for each tool.
182+
In this example, `toolA` provides the variables `ENV_VAR_1` and `ENV_VAR_2`,
183+
This will read the values of `ENV_VAR_1` through `ENV_VAR_4` from the current environment and set them for the credential.
184184
This is a direct mapping of environment variable names. **This is not recommended when overriding credentials for
185185
multiple tools that use the same environment variable names.**
186-
187-
#### 3. Environment Variable Mapping
188-
189-
`toolA:ENV_VAR_1->TOOL_A_ENV_VAR_1,ENV_VAR_2->TOOL_A_ENV_VAR_2;toolB:ENV_VAR_1->TOOL_B_ENV_VAR_1,ENV_VAR_2->TOOL_B_ENV_VAR_2`
190-
191-
In this example, `toolA` and `toolB` both provide the variables `ENV_VAR_1` and `ENV_VAR_2`.
192-
This will set the environment variables `ENV_VAR_1` and `ENV_VAR_2` to the values of `TOOL_A_ENV_VAR_1` and
193-
`TOOL_A_ENV_VAR_2` from the current environment for `toolA`. The same applies for `toolB`, but with the values of
194-
`TOOL_B_ENV_VAR_1` and `TOOL_B_ENV_VAR_2`. This is a mapping of one environment variable name to another.
195-
196-
### Real-World Example
197-
198-
Here is an example of how you can use a credential override to skip running the credential tool for the Brave Search tool:
199-
200-
```bash
201-
gptscript --credential-override "github.com/gptscript-ai/search/brave-credential:GPTSCRIPT_BRAVE_SEARCH_TOKEN->MY_BRAVE_SEARCH_TOKEN" github.com/gptscript-ai/search/brave '{"q": "cute cats"}'
202-
```
203-
204-
If you run this command, rather than being prompted by the credential tool for your token, GPTScript will read the contents
205-
of the environment variable `MY_BRAVE_SEARCH_TOKEN` and set that as the variable `GPTSCRIPT_BRAVE_SEARCH_TOKEN` when it runs
206-
the script.

pkg/runner/credentials.go

+3-11
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,9 @@ import (
77
)
88

99
// parseCredentialOverrides parses a string of credential overrides that the user provided as a command line arg.
10-
// The format of credential overrides can be one of three things:
10+
// The format of credential overrides can be one of two things:
1111
// cred1:ENV1,ENV2;cred2:ENV1,ENV2 (direct mapping of environment variables)
1212
// cred1:ENV1=VALUE1,ENV2=VALUE2;cred2:ENV1=VALUE1,ENV2=VALUE2 (key-value pairs)
13-
// cred1:ENV1->OTHER_ENV1,ENV2->OTHER_ENV2;cred2:ENV1->OTHER_ENV1,ENV2->OTHER_ENV2 (mapping to other environment variables)
1413
//
1514
// This function turns it into a map[string]map[string]string like this:
1615
//
@@ -36,15 +35,8 @@ func parseCredentialOverrides(override string) (map[string]map[string]string, er
3635
for _, env := range strings.Split(envs, ",") {
3736
key, value, found := strings.Cut(env, "=")
3837
if !found {
39-
var envVar string
40-
key, envVar, found = strings.Cut(env, "->")
41-
if found {
42-
// User did a mapping of key -> other env var, so look up the value.
43-
value = os.Getenv(envVar)
44-
} else {
45-
// User just passed an env var name as the key, so look up the value.
46-
value = os.Getenv(key)
47-
}
38+
// User just passed an env var name as the key, so look up the value.
39+
value = os.Getenv(key)
4840
}
4941
envMap[key] = value
5042
}

pkg/runner/credentials_test.go

+128
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,128 @@
1+
package runner
2+
3+
import (
4+
"os"
5+
"testing"
6+
7+
"github.com/stretchr/testify/require"
8+
)
9+
10+
func TestParseCredentialOverrides(t *testing.T) {
11+
cases := []struct {
12+
name string
13+
envs map[string]string
14+
in string
15+
out map[string]map[string]string
16+
expectErr bool
17+
}{
18+
{
19+
name: "empty",
20+
in: "",
21+
expectErr: true,
22+
},
23+
{
24+
name: "single cred, single env",
25+
envs: map[string]string{
26+
"ENV1": "VALUE1",
27+
},
28+
in: "cred1:ENV1",
29+
out: map[string]map[string]string{
30+
"cred1": {
31+
"ENV1": "VALUE1",
32+
},
33+
},
34+
},
35+
{
36+
name: "single cred, multiple envs",
37+
envs: map[string]string{
38+
"ENV1": "VALUE1",
39+
"ENV2": "VALUE2",
40+
},
41+
in: "cred1:ENV1,ENV2",
42+
out: map[string]map[string]string{
43+
"cred1": {
44+
"ENV1": "VALUE1",
45+
"ENV2": "VALUE2",
46+
},
47+
},
48+
},
49+
{
50+
name: "single cred, key value pairs",
51+
envs: map[string]string{
52+
"ENV1": "VALUE1",
53+
"ENV2": "VALUE2",
54+
},
55+
in: "cred1:ENV1=OTHERVALUE1,ENV2=OTHERVALUE2",
56+
out: map[string]map[string]string{
57+
"cred1": {
58+
"ENV1": "OTHERVALUE1",
59+
"ENV2": "OTHERVALUE2",
60+
},
61+
},
62+
},
63+
{
64+
name: "multiple creds, multiple envs",
65+
envs: map[string]string{
66+
"ENV1": "VALUE1",
67+
"ENV2": "VALUE2",
68+
},
69+
in: "cred1:ENV1,ENV2;cred2:ENV1,ENV2",
70+
out: map[string]map[string]string{
71+
"cred1": {
72+
"ENV1": "VALUE1",
73+
"ENV2": "VALUE2",
74+
},
75+
"cred2": {
76+
"ENV1": "VALUE1",
77+
"ENV2": "VALUE2",
78+
},
79+
},
80+
},
81+
{
82+
name: "multiple creds, key value pairs",
83+
envs: map[string]string{
84+
"ENV1": "VALUE1",
85+
"ENV2": "VALUE2",
86+
},
87+
in: "cred1:ENV1=OTHERVALUE1,ENV2=OTHERVALUE2;cred2:ENV1=OTHERVALUE3,ENV2=OTHERVALUE4",
88+
out: map[string]map[string]string{
89+
"cred1": {
90+
"ENV1": "OTHERVALUE1",
91+
"ENV2": "OTHERVALUE2",
92+
},
93+
"cred2": {
94+
"ENV1": "OTHERVALUE3",
95+
"ENV2": "OTHERVALUE4",
96+
},
97+
},
98+
},
99+
{
100+
name: "invalid format",
101+
in: "cred1=ENV1,ENV2",
102+
expectErr: true,
103+
},
104+
}
105+
106+
for _, tc := range cases {
107+
t.Run(tc.name, func(t *testing.T) {
108+
envs := tc.envs
109+
if envs == nil {
110+
envs = map[string]string{}
111+
}
112+
113+
for k, v := range envs {
114+
_ = os.Setenv(k, v)
115+
}
116+
117+
out, err := parseCredentialOverrides(tc.in)
118+
if tc.expectErr {
119+
require.Error(t, err)
120+
return
121+
}
122+
require.NoError(t, err)
123+
124+
require.Equal(t, len(tc.out), len(out), "expected %d creds, but got %d", len(tc.out), len(out))
125+
require.Equal(t, tc.out, out, "expected output %v, but got %v", tc.out, out)
126+
})
127+
}
128+
}

0 commit comments

Comments
 (0)