Skip to content

Commit 78ab228

Browse files
author
Gemini CLI
committed
feat: implement secret injection into skills and stream container output
1 parent bf8c2c1 commit 78ab228

File tree

2 files changed

+40
-1
lines changed

2 files changed

+40
-1
lines changed

internal/agent/agent.go

Lines changed: 29 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,8 @@ package agent
33
import (
44
"context"
55
"fmt"
6+
"io"
7+
"os"
68
"path/filepath"
79

810
"github.com/mackeh/AegisClaw/internal/approval"
@@ -11,6 +13,7 @@ import (
1113
"github.com/mackeh/AegisClaw/internal/policy"
1214
"github.com/mackeh/AegisClaw/internal/sandbox"
1315
"github.com/mackeh/AegisClaw/internal/scope"
16+
"github.com/mackeh/AegisClaw/internal/secrets"
1417
"github.com/mackeh/AegisClaw/internal/skill"
1518
)
1619

@@ -114,8 +117,28 @@ func ExecuteSkill(ctx context.Context, m *skill.Manifest, cmdName string, userAr
114117
return fmt.Errorf("execution blocked")
115118
}
116119

117-
// 6. Execute
120+
// 6. Prepare Execution Environment
118121
finalArgs := append(skillCmd.Args, userArgs...)
122+
env := append([]string{}, skillCmd.Env...)
123+
124+
// Inject Secrets if allowed
125+
if finalDecision == "allow" {
126+
cfgDir, _ := config.DefaultConfigDir()
127+
secretsDir := filepath.Join(cfgDir, "secrets")
128+
mgr := secrets.NewManager(secretsDir)
129+
130+
for _, s := range reqScopes {
131+
if s.Name == "secrets.access" && s.Resource != "" {
132+
val, err := mgr.Get(s.Resource)
133+
if err == nil {
134+
env = append(env, fmt.Sprintf("%s=%s", s.Resource, val))
135+
} else {
136+
fmt.Printf("⚠️ Warning: Secret '%s' requested but not found.\n", s.Resource)
137+
}
138+
}
139+
}
140+
}
141+
119142
fmt.Printf("🚀 Running skill: %s\n", m.Name)
120143

121144
exec, err := sandbox.NewDockerExecutor()
@@ -126,12 +149,17 @@ func ExecuteSkill(ctx context.Context, m *skill.Manifest, cmdName string, userAr
126149
result, err := exec.Run(ctx, sandbox.Config{
127150
Image: m.Image,
128151
Command: finalArgs,
152+
Env: env,
129153
Network: needsNetwork,
130154
})
131155
if err != nil {
132156
return fmt.Errorf("execution failed: %w", err)
133157
}
134158

159+
// Stream output
160+
io.Copy(os.Stdout, result.Stdout)
161+
io.Copy(os.Stderr, result.Stderr)
162+
135163
fmt.Printf("✅ Skill finished (exit code %d)\n", result.ExitCode)
136164
return nil
137165
}

skills/secret-test/skill.yaml

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
name: secret-test
2+
version: "1.0.0"
3+
description: "A skill to test secret injection"
4+
image: "alpine:latest"
5+
scopes:
6+
- "secrets.access:MY_API_KEY"
7+
commands:
8+
check:
9+
args: ["sh", "-c", "if [ -z \"$MY_API_KEY\" ]; then echo '❌ Secret NOT found'; else echo '✅ Secret found! Length: ${#MY_API_KEY}'; fi"]
10+
print-danger:
11+
args: ["sh", "-c", "echo \"Value is: $MY_API_KEY\""]

0 commit comments

Comments
 (0)