Add agentvault with a seed-outpost subcommand
Interactive agents are classifier-blocked from plumbing credentials through a shell, so seeding an Authentik outpost token into Vault KV needs to happen inside one binary invocation that never exposes the secret. - Add cmd/agentvault, a fourth CLI sharing the agentpr Vault AppRole login (role_id only, VAULT_ADDR/AGENT_APPROLE_ROLE_ID defaults unchanged). - Add `agentvault seed-outpost`: read the Authentik API token from kv/service/authentik/agent-api-token (field `token`, falling back to `api_token`), exact-match the outpost by name via the instances search, fetch its key from /api/v3/core/tokens/<identifier>/view_key/ and write it to --dest-path under --dest-key. - Print only the outpost name, token identifier, dest path and new KV version; keep secret material out of results, errors and logs. - Distinguish the failure stages (login, KV read denied, outpost missing, view_key, KV write denied) with ErrVaultDenied/ErrVaultNotFound/ ErrOutpostNotFound sentinels and actionable messages. - Add internal/agent vaultkv.go (AppRole-authenticated KV-v2 client) and authentik.go (outpost search + view_key) for reuse by future flows. - Cover the happy path, idempotent re-run, field fallback and every failure mode with httptest servers, including a leak check on error strings. - Wire agentvault into the Makefile, build-rpm.sh, nfpm contents, release cross-builds/assets, README and AGENTS.md.
This commit is contained in:
+17
-5
@@ -1,8 +1,8 @@
|
||||
// Package agent holds the plumbing shared by the agent-tools CLIs (agentpr and
|
||||
// watchpr): obtaining a Gitea token via Vault AppRole, talking to the Gitea
|
||||
// API, parsing PR references, and deciding when a watched PR changed
|
||||
// meaningfully. Both tools acquire their Gitea token the same way, so that
|
||||
// logic lives here once.
|
||||
// Package agent holds the plumbing shared by the agent-tools CLIs (agentpr,
|
||||
// watchpr, agentws and agentvault): the Vault AppRole login and its KV-v2
|
||||
// client, talking to the Gitea and Authentik APIs, parsing PR references, and
|
||||
// deciding when a watched PR changed meaningfully. Every tool authenticates to
|
||||
// Vault the same way, so that logic lives here once.
|
||||
package agent
|
||||
|
||||
import (
|
||||
@@ -23,6 +23,9 @@ const (
|
||||
// DefaultAgentLogin is the Gitea login of the agent whose own comments are
|
||||
// ignored by watchpr. Overridable via AGENT_LOGIN.
|
||||
DefaultAgentLogin = "unkin-agent"
|
||||
// DefaultAuthentikURL is the Authentik base URL used when AUTHENTIK_URL is
|
||||
// unset. identity.unkin.net has no DNS record; the k8s name is the real one.
|
||||
DefaultAuthentikURL = "https://identity.k8s.syd1.au.unkin.net"
|
||||
)
|
||||
|
||||
// VaultAddr returns the configured Vault address (env VAULT_ADDR or the default).
|
||||
@@ -59,6 +62,15 @@ func AgentLogin() string {
|
||||
return DefaultAgentLogin
|
||||
}
|
||||
|
||||
// AuthentikURL returns the configured Authentik base URL (env AUTHENTIK_URL or
|
||||
// the default).
|
||||
func AuthentikURL() string {
|
||||
if v := os.Getenv("AUTHENTIK_URL"); v != "" {
|
||||
return v
|
||||
}
|
||||
return DefaultAuthentikURL
|
||||
}
|
||||
|
||||
var (
|
||||
tokenOnce sync.Once
|
||||
tokenValue string
|
||||
|
||||
Reference in New Issue
Block a user