# Golem Add Secret Scala

> Golem Add Secret Scala is an Agent Skill for devops & security published in the golemcloud/golem repository on GitHub: a SKILL.md instruction file an AI agent can load to do this task.

Adding secrets to Scala Golem agents. Use when the user asks to add secret values, API keys, passwords, or sensitive configuration to a Scala Golem agent.

- Skill name: `golem-add-secret-scala`
- Category: [DevOps & Security](https://www.openparable.com/skill/devops-security/1)
- Source: https://github.com/golemcloud/golem/blob/HEAD/golem-skills/skills/scala/golem-add-secret-scala/SKILL.md
- Repository: golemcloud/golem (1,605 GitHub stars when collected)

## SKILL.md

# Adding Secrets to a Scala Golem Agent

## Overview

**Secrets** are sensitive configuration values (API keys, passwords, tokens) stored per-environment and accessed via `Secret[T]` from `golem.config`. They are declared inside config case classes alongside regular config fields, but the config value carries an opaque secret handle; plaintext is revealed only when agent code calls `.get`.

## Declaring Secrets

Wrap sensitive fields with `Secret[T]` in your config case class. `Secret[T]` has an implicit `Schema` derivation, so `Schema.derived` works automatically on parent case classes:

```scala
import golem.config.Secret
import zio.blocks.schema.Schema

final case class DbConfig(
  host: String,
  port: Int,
  password: Secret[String],
)

object DbConfig {
  implicit val schema: Schema[DbConfig] = Schema.derived
}

final case class MyAppConfig(
  appName: String,
  apiKey: Secret[String],
  db: DbConfig,
)

object MyAppConfig {
  implicit val schema: Schema[MyAppConfig] = Schema.derived
}
```

## Reading Secrets

`Secret[T]` is lazy — call `.get` to explicitly reveal the current value:

```scala
import golem.runtime.annotations.agentImplementation
import golem.config.Config

import scala.concurrent.Future

@agentImplementation()
final class MyAgentImpl(input: String, config: Config[MyAppConfig]) extends MyAgent {
  override def connect(): Future[String] = {
    val cfg = config.value
    val key = cfg.apiKey.get
    val pwd = cfg.db.password.get
    Future.successful(s"Connected to ${cfg.db.host}:${cfg.db.port}")
  }
}
```

## Managing Secrets via CLI

Secret paths use camelCase, matching Scala field names:

```shell
golem secret create apiKey --secret-type String --secret-value "sk-abc123"
golem secret create db.password --secret-type String --secret-value "s3cret"
golem secret list
golem secret update-value apiKey --secret-value "new-value"
golem secret delete apiKey
```

> **Note:** For `update-value` and `delete`, you can also use `--id <uuid>` instead of the positional path.

## Secret Defaults in golem.yaml

Use `secretDefaults` for local development only — manage production secrets via CLI:

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

## Key Constraints

- `Secret[T]` is lazy — call `.get` to reveal the actual value
- Each reveal pins the resolved secret revision for deterministic retries and replay; fresh `.get` calls can observe runtime updates
- Secret values are stored per-environment, not per-agent-instance
- The `Secret[T]` companion provides an implicit `Schema` so `Schema.derived` works on parent case classes
- Missing required secrets cause agent creation to fail
- Secret paths use camelCase (matching Scala field names)
- The `--secret-type` argument accepts Scala type names: `String`, `Int`, `Boolean`, `List[String]`, `Option[Int]` (JSON-encoded analysed types like `'{"type":"Str"}'` are also supported as a fallback)
- Use `secretDefaults` in `golem.yaml` only for development; manage production secrets via CLI
- If the agent also needs non-secret typed config guidance, use `golem-add-config-scala` alongside this skill

---

Source: https://www.openparable.com/skill/devops-security/golem-add-secret-scala (OpenParable). Cite the canonical URL above.
