golemcloud/golem/golem-add-secret-go

Trust tier 3
  • community
Source check pending

Checking that the SKILL.md file is still in the repository.

Adding typed secrets to a Go Golem agent with golem.Secret[T]. Use when the user needs API keys, passwords, or tokens that must not be checked into source control in a Go Golem project.

Install

npx vskill@latest install golemcloud/golem/golem-add-secret-go

SKILL.md

Adding Secrets to a Go Agent

Overview

Secrets are sensitive configuration values (API keys, passwords, tokens) read at runtime through golem.Secret[T]. A secret uses the same config mechanism as regular typed config — it is just a field whose type is golem.Secret[T] inside the agent's config struct (see golem-add-config-go). The config value carries an opaque secret handle; the plaintext is revealed only when your code calls .Get() or .MustGet().

Manage secrets per environment via the CLI. Use secretDefaults in golem.yaml only for development placeholders; never commit real credentials.

Steps

  1. Add a `golem.Secret[T]` field to the agent's config struct.
  2. Define / implement the agent as a configured agent (DefineConfiguredAgent + ImplementConfigured).
  3. Reveal the value at runtime with .MustGet(), or .Get() to handle a read failure.
  4. Provide values via secretDefaults (local) or the CLI (per environment).

Declaring a Secret Field

A secret is any field of type golem.Secret[T], at any depth of the config struct:

go
// Package client is the DEFINITION of an API-client agent.
package client
import "github.com/golemcloud/golem/sdks/go/golem"
type ID struct{ Name string }
type Config struct {
Endpoint string
APIKey golem.Secret[string] // a secret leaf
DB DBConfig
}
type DBConfig struct {
Host string
Password golem.Secret[string] // secret at path db.password
}
var Agent = golem.DefineConfiguredAgent[ID, Config](golem.Spec{
Name: "ClientAgent",
Description: "Calls an external API using a secret key",
})
var Connect = Agent.Method[golem.Unit, string]("connect", golem.Description("Describe the connection using secret values"))

Reading a Secret at Runtime

Read the config, then call .MustGet() on the config-backed secret field to reveal the current plaintext. Each config-backed read resolves a fresh handle, so live reads observe rotation; retry/replay uses the recorded revision. A received RPC handle instead stays pinned to its transferred revision. .Get() returns (T, error) instead, for a secret that may be unavailable:

go
// Package impl is the IMPLEMENTATION of the API-client agent.
package impl
import (
"fmt"
"myapp/agents/client"
"github.com/golemcloud/golem/sdks/go/golem"
)
type state struct{}
var agent = client.Agent.ImplementConfigured(func(_ *golem.InitContext[client.ID, state, client.Config]) *state { return &state{} })
func init() {
agent.Handle(client.Connect, func(ctx *golem.Context[state], _ golem.Unit) string {
cfg := ctx.Config(client.Agent)
apiKey := cfg.APIKey.MustGet() // reveals the current plaintext
dbPass := cfg.DB.Password.MustGet() // secret at any depth
return fmt.Sprintf("connecting to %s (key len=%d, db host=%s, pw len=%d)",
cfg.Endpoint, len(apiKey), cfg.DB.Host, len(dbPass))
})
}

A golem.Secret[T] cannot be constructed from a plaintext: it comes from the agent's config, or from another agent. Its String()/GoString() render as golem.Secret(redacted), so it stays out of logs formatted with %v/%s.

Passing a Secret to Another Agent

A golem.Secret[T] can be a field of a method's input or its result. It travels as a secret handle, never as plaintext, and the receiver reveals it with .Get() / .MustGet():

go
var Share = Agent.Method[golem.Unit, golem.Secret[string]]("share")
agent.Handle(Share, func(ctx *golem.Context[state], _ golem.Unit) golem.Secret[string] {
return ctx.Config(Agent).APIKey
})
// in another agent
key := client.Share.MustCall(client.Agent.Get(client.ID{Name: "keeper"}), golem.Unit{}).MustGet()

A config secret can be sent again; a secret you received moves when you send it on, and the copy that was sent is unusable afterwards (golem.ErrSecretMoved). External clients cannot carry secrets.

A transferred handle is pinned to one secret revision. Repeated .Get() calls on that received handle do not observe rotation. To give a recipient the rotated value, send a newly resolved handle from the config-backed secret; the recipient must use the new handle.

Secret Defaults in golem.yaml (development only recommended)

For local development, set placeholder defaults under secretDefaults.<environment>. Keys are camelCase and follow the same path flattening as config; nested structs are nested maps. The CLI selects defaults by environment name, with no production exclusion. Keep defaults development-only and never commit real credentials:

yaml
secretDefaults:
local:
apiKey: "dev-key-123"
db:
password: "dev-password"

Managing Secrets via CLI (per environment)

Outside local defaults, secrets are environment-scoped — each deployment environment has its own values, set through the platform CLI (paths use the same camelCase as the config keys):

shell
golem secret create apiKey --type string --value "sk-abc123"
golem secret create db.password --type string --value "s3cret"
# Without a value option the value is prompted for (hidden input); or pipe it in
printenv DB_PASSWORD | golem secret create db.password --type string --value-stdin
# Create, or update the value if the secret already exists
golem secret create apiKey --type string --value "sk-abc123" --update-existing
# List, update, clear, and delete (delete asks for confirmation; --yes skips it)
golem secret list
golem secret update apiKey --value "new-value"
golem secret update apiKey --unset
golem secret delete apiKey

Key Constraints

  • A secret is a config field of type golem.Secret[T] — the agent must be a configured agent (DefineConfiguredAgent / ImplementConfigured); see golem-add-config-go.
  • Only `.Get()` / `.MustGet()` reveal the plaintext. Config-backed live reads resolve fresh handles and observe rotation without restarting the agent; retry/replay uses the recorded revision. Received handles stay pinned to their transferred revision and require a new handle to observe rotation.
  • Use the CLI for production secret values. secretDefaults applies by environment name, even in production; restrict it to development placeholders and never commit real credentials.
  • Deployment can succeed with an unset secret; a missing required secret fails agent creation, not deployment. Read a secret from within an invocation only — .Get() calls the host. It returns an error when the secret is unavailable, its version is gone, or it was moved; .MustGet() panics instead, which traps the component (fails the agent), as in Rust.
  • Over RPC, secret fields are always platform-provisioned; a definition's WithConfig overrides only local config, never secrets.
Related Skills
SkillWhen to Load
golem-add-config-goThe non-secret typed-config mechanism secrets build on
golem-add-agent-goDefine the base agent the config attaches to
golem-call-another-agent-goUnderstand why secrets are not overridable over RPC

Security

  • Security scanPassed, 90 of 100Pattern checks on the skill's files.
  • Model reviewPassed

Quality evaluation

  • Task evaluationNot runNo evaluation yet. Run one in Skill Studio.

Source

Popularity

7-day trend score
0

Not refreshed yet.

Works with

Any agent vskill installs to: 56 targets in all. These 39 have a page on this site.

  • Claude Code
  • Cursor
  • GitHub Copilot
  • Windsurf
  • Codex
  • Gemini CLI
  • Cline
  • Amp
  • Roo Code
  • Goose
  • Continue
  • Kilo Code
  • Junie
  • Trae
  • OpenHands
  • Qwen Code
  • AI Agent
  • Tabnine Chat
  • Sourcegraph Cody
  • Amazon Q
  • Firebase Genkit
  • Sweep
  • Devin
  • Phind
  • Mentat
  • Claude Desktop
  • Aider
  • GPT Pilot
  • Plandex
  • bolt.new
  • v0
  • Replit Agent
  • Anse
  • TypingMind
  • BetterChatGPT
  • LibreChat
  • Warp AI
  • Pieces
  • Fig AI
Embed badge
vskill VERIFIED badge
[![vskill VERIFIED](https://verified-skill.com/api/v1/skills/golemcloud/golem/golem-add-secret-go/badge)](https://verified-skill.com/skills/golemcloud/golem/golem-add-secret-go)

Something wrong with this skill or its page? Tell us.