Documentation
¶
Overview ¶
Package configurations routes service configurations and DNS declarations between codefly services.
A "configuration" is a typed key/value bundle a service publishes for its dependents to consume — postgres exposes a connection string, vault exposes a token, an auth service exposes a JWKS URL. The Manager type aggregates configurations from every service in dependency order and injects them into dependent services as environment variables (CODEFLY__SERVICE_<NAME>__...).
DNS declarations live alongside configurations: a service can ship a dns/<env>/dns.codefly.yaml to override its in-cluster Service hostname per deploy environment (used historically for host.docker.internal in local-mode `codefly run`). The Manager exposes those via GetDNS for the network package's RemoteManager to consume; missing DNS is now a non-fatal — the network layer synthesizes <svc>.<ns>.svc.cluster.local in cluster envs.
Loader is the abstract interface a service must implement to plug into the manager (Identity, Load, Configurations, DNS). Concrete loaders live in core/cli and similar consumer packages.
Secrets ¶
Git worktrees share repository history but not ignored files. Copying or symlinking plaintext secrets from another checkout makes that checkout a secret authority and exposes credentials to every process that can read the worktree. Reference-only manifests separate commit-safe discovery data from resolved credentials.
Files named *.secret.ref.env and *.secret.ref.yaml are reference-only secret manifests. Every value, including every scalar nested in YAML maps and arrays, must be a recognized provider reference:
# auth.secret.ref.env CLIENT_SECRET=op://development-vault/auth-service/client-secret # database.secret.ref.yaml credentials: password: op://development-vault/database/password
Both names map to the configuration name before .secret.ref and are always secret. Their contract applies in local environments too, and mixing either format with a plaintext-capable source for the same logical configuration is a load error.
Backends are selected per environment via workspace.codefly.yaml. It is a list so more backends can be added later:
environments:
- name: local
secrets:
- kind: 1password
account: my-team
Reference-only manifests are safe to commit by construction: plaintext, unknown schemes, malformed references, duplicate legacy/reference sources, and references without a configured backend all fail the load. Provider output is resolved in memory and is never written back to the manifest or included in provider failure output. A subsequent load resolves the stable reference again, so provider-side rotation requires no Git change.
1Password is the only backend today; SecretResolver is the seam for adding AWS Secrets Manager, Doppler, Vault, etc.
Legacy *.secret.env and *.secret.yaml files remain a local plaintext escape hatch. They are ambiguous by design, must stay ignored by Git, and must not be copied or symlinked between worktrees. A locked, unavailable, or misconfigured provider fails closed; Codefly does not fall back to raw environment variables or values from a worktree manager.
Project ignore rules should include:
*.secret.env *.secret.yaml
Manager.Restrict prevents resolution for excluded service origins. Workspace configurations are currently resolved during Manager.Load, before dependency names passed later to GetWorkspaceDependenciesConfigurations are known. Reference-only manifests do not change the loader's existing symlink traversal policy; filesystem and repository permissions remain the boundary.
Git owns the non-secret manifest and workspace configuration, Core validates and resolves only provider references, the CLI selects the declared environment, and applications consume only the configuration Codefly routes to them. Worktree managers may run readiness checks but do not provision plaintext. See secrets.go (SecretResolver, ParseSecretReference, ResolversFromEnvironment).
Index ¶
- Constants
- Variables
- func ConfigurationInformationDataFromFile(ctx context.Context, name string, p string, isSecret bool) (*basev0.ConfigurationInformation, error)
- func ConsolidateInfo(_ context.Context, infos []*basev0.ConfigurationInformation) ([]*basev0.ConfigurationInformation, error)
- func ExtractFromPath(p string) string
- func InformationUnmarshal(info *basev0.ConfigurationInformation, v interface{}) error
- func LoadConfigurationInformationsFromFiles(ctx context.Context, dir string) ([]*basev0.ConfigurationInformation, error)
- type ConfigurationInformationLocalReader
- func (local *ConfigurationInformationLocalReader) Configurations() []*basev0.Configuration
- func (local *ConfigurationInformationLocalReader) DNS() []*basev0.DNS
- func (local *ConfigurationInformationLocalReader) Identity() string
- func (local *ConfigurationInformationLocalReader) Load(ctx context.Context, env *resources.Environment) error
- type ConfigurationInformationWrapper
- type ConfigurationSource
- type Loader
- type Manager
- func (manager *Manager) DNS() []*basev0.DNS
- func (manager *Manager) ExposeConfiguration(ctx context.Context, service *resources.ServiceIdentity, ...) error
- func (manager *Manager) GetDNS(ctx context.Context, svc *resources.ServiceIdentity, endpointName string) (*basev0.DNS, error)
- func (manager *Manager) GetServiceConfiguration(_ context.Context, service *resources.ServiceIdentity) (*basev0.Configuration, error)
- func (manager *Manager) GetServiceConfigurations(_ context.Context) ([]*basev0.Configuration, error)
- func (manager *Manager) GetSharedServiceConfiguration(_ context.Context, unique string) ([]*basev0.Configuration, error)
- func (manager *Manager) GetWorkspaceConfigurations(_ context.Context) ([]*basev0.Configuration, error)
- func (manager *Manager) GetWorkspaceDependenciesConfigurations(ctx context.Context, deps ...string) ([]*basev0.Configuration, error)
- func (manager *Manager) Load(ctx context.Context, env *resources.Environment) error
- func (manager *Manager) LoadConfigurations(_ context.Context) error
- func (manager *Manager) LoadDNS(_ context.Context) error
- func (manager *Manager) Restrict(_ context.Context, values []*resources.ServiceIdentity) error
- func (manager *Manager) WithLoader(loader Loader) *Manager
- func (manager *Manager) WithSecretResolver(resolvers ...SecretResolver) *Manager
- type OnePasswordResolver
- type SecretReference
- type SecretResolver
Constants ¶
const OnePasswordScheme = "op"
Legacy *.secret.* files accept either local plaintext or provider references. Files named *.secret.ref.* are validated by the local reader so every value must be a reference. A reference is a URI whose scheme names a provider:
client_secret: op://dev-vault/auth0/client_secret
Reference-only manifests are safe to commit; legacy secret files are not. Resolved values never touch disk. In legacy files only known schemes are references, so a postgres:// plaintext value still passes through. The SecretResolver seam allows additional backends without changing loaders.
const ProviderOnePassword = "1password"
ProviderOnePassword is the `secrets.kind` that selects the 1Password backend.
Variables ¶
var ErrConfigurationConflict = errors.New("configuration definitions conflict")
ErrConfigurationConflict marks configuration definitions that cannot be composed into one logical configuration. Callers should use errors.Is instead of matching the human-readable diagnostic.
var ErrSecretProviderAuthenticationRequired = errors.New("secret provider authentication required")
ErrSecretProviderAuthenticationRequired marks a provider failure that can be resolved by authenticating or unlocking the provider. Provider output is intentionally not exposed through the returned error.
Functions ¶
func ConfigurationInformationDataFromFile ¶ added in v0.1.127
func ConsolidateInfo ¶ added in v0.1.123
func ConsolidateInfo(_ context.Context, infos []*basev0.ConfigurationInformation) ([]*basev0.ConfigurationInformation, error)
ConsolidateInfo consolidate informations values per name
func ExtractFromPath ¶ added in v0.1.89
ExtractFromPath gets modules/app/services/ServiceWithModule and we want to extract app/ServiceWithModule
func InformationUnmarshal ¶ added in v0.1.126
func InformationUnmarshal(info *basev0.ConfigurationInformation, v interface{}) error
func LoadConfigurationInformationsFromFiles ¶ added in v0.1.123
func LoadConfigurationInformationsFromFiles(ctx context.Context, dir string) ([]*basev0.ConfigurationInformation, error)
LoadConfigurationInformationsFromFiles returns all configurations infos Naming is path based with respect to dir
Types ¶
type ConfigurationInformationLocalReader ¶ added in v0.1.89
type ConfigurationInformationLocalReader struct {
// contains filtered or unexported fields
}
func NewConfigurationLocalReader ¶ added in v0.1.89
func (*ConfigurationInformationLocalReader) Configurations ¶ added in v0.1.89
func (local *ConfigurationInformationLocalReader) Configurations() []*basev0.Configuration
func (*ConfigurationInformationLocalReader) DNS ¶ added in v0.1.89
func (local *ConfigurationInformationLocalReader) DNS() []*basev0.DNS
func (*ConfigurationInformationLocalReader) Identity ¶ added in v0.1.89
func (local *ConfigurationInformationLocalReader) Identity() string
func (*ConfigurationInformationLocalReader) Load ¶ added in v0.1.89
func (local *ConfigurationInformationLocalReader) Load(ctx context.Context, env *resources.Environment) error
type ConfigurationInformationWrapper ¶ added in v0.1.89
type ConfigurationInformationWrapper struct {
*basev0.ConfigurationInformation
}
type ConfigurationSource ¶ added in v0.1.89
type ConfigurationSource struct {
ServiceWithModule *resources.ServiceWithModule
Name string
}
func FromService ¶ added in v0.1.89
func FromService(service *resources.ServiceIdentity, dep string) (*ConfigurationSource, error)
FromService satisfies this format - Name - unique:Name
type Loader ¶ added in v0.1.89
type Loader interface {
Identity() string
Load(ctx context.Context, env *resources.Environment) error
// Configurations returns the configurations produced by Load. It must
// return the same instances on every call (not fresh copies): after Load,
// the Manager resolves secret references in these objects in place, and
// LoadConfigurations reads them back expecting the resolved values.
Configurations() []*basev0.Configuration
DNS() []*basev0.DNS
}
type Manager ¶ added in v0.1.89
type Manager struct {
// contains filtered or unexported fields
}
func NewManager ¶ added in v0.1.89
func (*Manager) ExposeConfiguration ¶ added in v0.1.89
func (manager *Manager) ExposeConfiguration(ctx context.Context, service *resources.ServiceIdentity, confs ...*basev0.Configuration) error
func (*Manager) GetServiceConfiguration ¶ added in v0.1.89
func (manager *Manager) GetServiceConfiguration(_ context.Context, service *resources.ServiceIdentity) (*basev0.Configuration, error)
func (*Manager) GetServiceConfigurations ¶ added in v0.1.123
func (*Manager) GetSharedServiceConfiguration ¶ added in v0.1.89
func (*Manager) GetWorkspaceConfigurations ¶ added in v0.1.123
func (*Manager) GetWorkspaceDependenciesConfigurations ¶ added in v0.1.123
func (*Manager) LoadConfigurations ¶ added in v0.1.89
LoadConfigurations fetch different loaders and consolidate
func (*Manager) WithLoader ¶ added in v0.1.89
func (*Manager) WithSecretResolver ¶ added in v0.2.15
func (manager *Manager) WithSecretResolver(resolvers ...SecretResolver) *Manager
WithSecretResolver registers a secret resolver. Resolvers selected by the environment's `secrets` block are added automatically at Load() time; this is for tests and custom backends.
type OnePasswordResolver ¶ added in v0.2.15
type OnePasswordResolver struct {
// contains filtered or unexported fields
}
OnePasswordResolver resolves op://vault/item/field references through the 1Password `op` CLI. `op read` accepts the full URI and prints the field value to stdout — biometric/session unlock is handled by the CLI itself.
func NewOnePasswordResolver ¶ added in v0.2.15
func NewOnePasswordResolver(account string) *OnePasswordResolver
func (*OnePasswordResolver) Resolve ¶ added in v0.2.15
func (r *OnePasswordResolver) Resolve(ctx context.Context, ref *SecretReference) (string, error)
func (*OnePasswordResolver) Scheme ¶ added in v0.2.15
func (r *OnePasswordResolver) Scheme() string
type SecretReference ¶ added in v0.2.15
SecretReference is a parsed secret URI, e.g. op://vault/item/field.
func ParseSecretReference ¶ added in v0.2.15
func ParseSecretReference(value string) (*SecretReference, bool)
ParseSecretReference reports whether value is a known, non-empty secret reference and, if so, splits it into scheme and path. Unknown schemes return false so legacy secret files continue to treat them as plaintext.
type SecretResolver ¶ added in v0.2.15
type SecretResolver interface {
Scheme() string
Resolve(ctx context.Context, ref *SecretReference) (string, error)
}
SecretResolver resolves references for a single backend.
func ResolversFromEnvironment ¶ added in v0.2.15
func ResolversFromEnvironment(env *resources.Environment) ([]SecretResolver, error)
ResolversFromEnvironment builds the secret resolvers an environment selects via its `secrets` block. With no providers, legacy plaintext remains verbatim while any provider reference fails during resolution.