Get started¶
A minimal FlexConf setup in four steps: install → declare → configure →
secrets. New to FlexConf? Start with the overview. For
depth, see the user guide; the specs
are the normative source of truth.
Install¶
Declare your configuration¶
Configuration is a plain Go struct with flexconf tags. Defaults live in Go —
pre-populate the struct before loading:
package main
import (
"log"
"time"
"github.com/sylvanld/go-flexconf/flexconf"
"github.com/sylvanld/go-flexconf/flexprompt"
_ "github.com/sylvanld/go-flexconf/flexvault/driver/keepass" // (1)!
)
type Config struct {
Service string `flexconf:"service,required"`
Timeout time.Duration `flexconf:"timeout"`
Token string `flexconf:"token"` // (2)!
}
func main() {
flexconf.RunAgentIfRequested() // (3)!
flexprompt.SetPrompter(flexprompt.NewCLIPrompter())
cfg := Config{Timeout: 30 * time.Second} // (4)!
if err := flexconf.New("/etc/myapp", "./config").Load("config.yaml", &cfg); err != nil {
log.Fatal(err)
}
log.Printf("service=%s timeout=%s", cfg.Service, cfg.Timeout)
}
- Blank-import the secret backend(s) you want available.
- May be
$(secret:…)— the type doesn't care where the value comes from. - Must be first in
main: enables agent-backed secret resolution. - Defaults live in Go — pre-populate before loading.
Layers & binding
flexconf.New takes config directories as layers, ordered lowest →
highest precedence: maps deep-merge by key, scalars and sequences are
replaced wholesale. Binding is all-or-nothing — on any error your struct
is left exactly as passed. See loading configuration
and schema & binding.
Write the config file¶
# ./config/config.yaml
service: api
timeout: 10s
token: $(secret:artifactory/token) # (1)!
url: https://$(env:HOST)/api # (2)!
- Resolved via the operator's vault registry — see step 4.
- Tokens can be embedded in literal text.
Values may contain $(scheme:path) tokens, resolved at load time:
| Token | Resolves to |
|---|---|
$(env:NAME) |
|
$(file:path) |
|
$(config:other.yaml) |
|
$(secret:namespace/key) |
$(secret:vault:ns/key)). |
See templating & resolvers for the full grammar, escaping, and custom resolvers.
Set up secrets¶
Secrets never live in config files — $(secret:…) tokens are looked up in a
vault registry owned by the operator:
# ~/.config/flexconf/vaults.yaml
default: personal
vaults:
personal:
driver: keepass
path: ~/.local/share/flexconf/personal.kdbx
Create, unlock, and populate the vault with the CLI:
$ flexconf secret init
New KeePass master password: ****
created vault "personal"
$ flexconf secret unlock
KeePass master password: ****
unlocked; agent will lock after idle timeout
$ echo -n 'tok' | flexconf secret set artifactory/token
ok
The secret agent
unlock spawns a detached, ssh-agent-style background agent that
holds the unlocked vault in memory and auto-locks after an idle timeout
(default 2 minutes). Your application then resolves $(secret:…) tokens
through the agent without ever prompting — or, when no agent is running,
prompts via the flexprompt prompter you configured in step 2.
See the vault registry,
secret resolution, and the CLI —
including how to mount the same secret command group into your own app's CLI
with flexcli.
Going further¶
That's the whole loop — typed config, layered files, vault-backed secrets.
To dive deeper into any part of it (templating grammar, variants,
custom resolvers, vault drivers, …), head to the
User guide.