owl

package
v3.16.11 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Apr 23, 2026 License: Apache-2.0 Imports: 27 Imported by: 0

README

+++ [runme] id = '01HRA297WC2HJP7X48FM3DR1V0' version = 'v3' +++

The Owl Store 🦉

What is it?

Owl Store

A ENV solution for Humans and Workloads:

  • Specify, Validate, and Resolve ENV vars
  • Verification of “Correctness” & better tools

Took inspiration from

  • The SSH-Agent
  • How Typescript brings type-safety to Javascript

Why?

  • Make idea of "SSO for your Environments" come to live
  • The 🦉 knows best, because she's the wisest of birds in the animal kingdom

Learn more: Typed Environment Variables

Environment “Specs”

The .env.example frontend/facade:

JWT_SECRET=Secret to sign authed JWT tokens # Secret!
ANON_KEY=Secret to sign anonymous JWT tokens # Secret!
SERVICE_ROLE_KEY=JWT to assume the service role # JWT
POSTGRES_PASSWORD=Password for the postgres user # Password!
DASHBOARD_USERNAME=Username for the dashboard # Plain!
DASHBOARD_PASSWORD=Password for the dashboard # Password!
SOME_OTHER_VAR=Needs a matching value # Regex(/^[a-z...a. -]+\.)
Philosophy
  • Composable, extensible, and progressive
  • Queryable resolution thanks to Graph (DAG)
  • Use Auth-Context, Machine & Runtime info, etc
  • Connect to SOPS, Secret Managers, CLI tools etc
  • E.g. different resolution paths per ENV class
  • OWL easily better three letter acronym than ENV
  • .env files on outside - Graph Engine on inside
  • Progressive: use as much or little as you need
  • Different facades possible e.g. CRDs, YAML-dialect, SDKs
  • Runme’s fallback resolution → “securely prompt user”
  • Get involved, help building out owl toolkit & ecosystem

Define ENV spec inside code repository

Relationship

Anatomy of Environment Vars ⇄ “Specs”

Specs

Extensible at every stage

Resolution (e.g. translated env.owl.yaml or JS/Golang/Java/etc SDKs)
query ResolveEnv(...) {
   ...
   render {
      withCell(ulid: "01HRA297WC2HJP7X48FM3DR1V0") {
         withShell(command: "terraform output -json | jq -r .workspace_vars.value.{}") {
            command
            withWebhook(url: "https://secrets.platform.runme.dev/resolver") {
               url
               withStateful(org: "acme-corp") {
                  org
                  dotenv(prefix: "VITE_REACT_APP_", export: false)
                  snapshot {
                     ...
                  }
               }
            }
         }
      }
   }
}
.env-Frontend (query ASTs rendered in text for illustration)
query LoadDotEnvs {
    process {
        path
        file(paths: ["env.spec", ".env.example"], ignoreSpecs: false) {
            path
            file(paths: [".env.local", ".env"]) {
                path
                vars
                specs
            }
        }
    }
}

Common set of Specs (not all available yet)

  • Plain

    • Opaque
    • Regex(...)
    • ...
  • Secret

    • Password
    • JWT
    • x509Cert
    • ...
  • Resources

    • DbUrl
    • Redis
    • ...
  • Cred Sets (non-atomic)

    • FirebaseSdk
    • OpenAI
    • ...

Documentation

Index

Constants

View Source
const (
	AtomicNameOpaque   string = "Opaque"   // SpecNameOpaque specifies an opaque specification.
	AtomicNamePlain    string = "Plain"    // SpecNamePlain specifies a plain specification.
	AtomicNameSecret   string = "Secret"   // SpecNameSecret specifies a secret specification.
	AtomicNamePassword string = "Password" // SpecNamePassword specifies a password specification.
	AtomicNameDefault         = AtomicNameOpaque
)

Constants representing different spec names. These constants are of type AtomicName and are assigned string values.

View Source
const (
	OwlEnvSpecDefsKey owlContextKey = iota
	OwlGcpCredentialsKey
)
View Source
const (
	DeleteSetOperation setOperationKind = iota
	LoadSetOperation
	ReconcileSetOperation
	ResolveSetOperation
	TransientSetOperation
	UpdateSetOperation
)
View Source
const SpecTypeKey string = "Spec"

Variables

View Source
var (
	Schema      graphql.Schema
	AtomicTypes map[string]*atomicType
	SpecType    *atomicType
)
View Source
var EnvironmentType,
	EnvSpecsType,
	ValidateType,
	ResolveType,
	RenderType,
	SpecTypeErrorsType *graphql.Object

Functions

This section is empty.

Types

type AtomicResolverMutator

type AtomicResolverMutator func(val *SetVarValue, spec *SetVarSpec, insecure bool)

type Operation

type Operation struct {
	// contains filtered or unexported fields
}

type OperationSet

type OperationSet struct {
	SpecDef
	// contains filtered or unexported fields
}

func NewOperationSet

func NewOperationSet(opts ...OperationSetOption) (*OperationSet, error)

type OperationSetOption

type OperationSetOption func(*OperationSet) error

func WithItems

func WithItems(items SetVarItems) OperationSetOption

func WithOperation

func WithOperation(operation setOperationKind) OperationSetOption

func WithSpecs

func WithSpecs(included bool) OperationSetOption

type Query

type Query struct {
	// contains filtered or unexported fields
}

func (*Query) Print

func (q *Query) Print() (string, error)

type RequiredError

type RequiredError struct {
	// contains filtered or unexported fields
}

func NewRequiredError

func NewRequiredError(varItem *SetVarItem) *RequiredError

func (RequiredError) Code

func (RequiredError) Error

func (e RequiredError) Error() string

func (RequiredError) Key

func (e RequiredError) Key() string

func (RequiredError) Message

func (e RequiredError) Message() string

func (RequiredError) Source

func (e RequiredError) Source() string

func (RequiredError) SpecName

func (e RequiredError) SpecName() string

func (RequiredError) String

func (e RequiredError) String() string

func (RequiredError) VarItem

func (e RequiredError) VarItem() *SetVarItem

type ResolutionFailedError

type ResolutionFailedError struct {
	// contains filtered or unexported fields
}

func NewResolutionFailedError

func NewResolutionFailedError(varItem *SetVarItem, item string, err error) *ResolutionFailedError

func (ResolutionFailedError) Code

func (ResolutionFailedError) Error

func (e ResolutionFailedError) Error() string

func (ResolutionFailedError) Item

func (e ResolutionFailedError) Item() string

func (ResolutionFailedError) Key

func (e ResolutionFailedError) Key() string

func (ResolutionFailedError) Message

func (e ResolutionFailedError) Message() string

func (ResolutionFailedError) Source

func (e ResolutionFailedError) Source() string

func (ResolutionFailedError) SpecName

func (e ResolutionFailedError) SpecName() string

func (ResolutionFailedError) String

func (e ResolutionFailedError) String() string

func (ResolutionFailedError) VarItem

func (e ResolutionFailedError) VarItem() *SetVarItem

type ResolveOperationSet

type ResolveOperationSet struct {
	*OperationSet
	*SpecOperationSet

	Project string
	Mapping map[string]string
}

type SetVar

type SetVar struct {
	Key    string `json:"key"`
	Origin string `json:"origin,omitempty"`
	// Operation *setVarOperation `json:"operation"`
	Created *time.Time `json:"created,omitempty"`
	Updated *time.Time `json:"updated,omitempty"`
}

type SetVarError

type SetVarError struct {
	Code    int    `json:"code,omitempty"`
	Message string `json:"message,omitempty"`
}

type SetVarItem

type SetVarItem struct {
	Var    *SetVar        `json:"var,omitempty"`
	Value  *varValue      `json:"value,omitempty"`
	Spec   *varSpec       `json:"spec,omitempty"`
	Errors []*SetVarError `json:"errors,omitempty"`
}

type SetVarItems

type SetVarItems []*SetVarItem

type SetVarSpec

type SetVarSpec struct {
	Var  *SetVar  `json:"var,omitempty"`
	Spec *varSpec `json:"spec,omitempty"`
}

type SetVarValue

type SetVarValue struct {
	Var   *SetVar   `json:"var,omitempty"`
	Value *varValue `json:"value,omitempty"`
}

type Spec

type Spec struct {
	Name     string
	Required bool // Indicates whether the configuration is required.
	Valid    bool // Indicates whether the configuration is valid.
}

Spec represents the available configuration options and their flags.

type SpecDef

type SpecDef struct {
	Name      string              `json:"name"`
	Breaker   string              `json:"breaker"`
	Atomics   map[string]*varSpec `json:"atomics" yaml:"-"`
	Validator func(item *varSpec, itemKey string, varItem *SetVarItem) (ValidationErrors, error)
}

func (*SpecDef) Validate

func (cd *SpecDef) Validate(itemKey string, varItem *SetVarItem) (ValidationErrors, error)

type SpecDefs

type SpecDefs map[string]*SpecDef

type SpecOperationSet

type SpecOperationSet struct {
	*OperationSet
	Name      string
	Namespace string
	Keys      []string
}

func (*SpecOperationSet) GetAtomic

func (s *SpecOperationSet) GetAtomic(spec *SetVarSpec, specDefs SpecDefs) (string, *SetVarItem, error)

type Specs

type Specs map[string]Spec

Specs represents a collection of configuration specifications.

func ParseRawSpec

func ParseRawSpec(values map[string]string, comments map[string]string) Specs

GenerateSpecsFromComments maps comments to configuration key specifications.

type Store

type Store struct {
	// contains filtered or unexported fields
}

func NewStore

func NewStore(opts ...StoreOption) (*Store, error)

func (*Store) DoQuery

func (s *Store) DoQuery(query string, vars map[string]interface{}, resolve bool) (*graphql.Result, error)

func (*Store) InsecureGet

func (s *Store) InsecureGet(k string) (string, bool, error)

func (*Store) InsecureResolve

func (s *Store) InsecureResolve() (SetVarItems, error)

func (*Store) InsecureValues

func (s *Store) InsecureValues() ([]string, error)

func (*Store) LoadEnvs

func (s *Store) LoadEnvs(source string, envs ...string) error

func (*Store) NewQuery

func (s *Store) NewQuery(queryName, rootSelelection string, varDefs []*ast.VariableDefinition, reducers []QueryNodeReducer) (*Query, error)

func (*Store) SensitiveKeys

func (s *Store) SensitiveKeys() ([]string, error)

func (*Store) Snapshot

func (s *Store) Snapshot() (SetVarItems, error)

func (*Store) Update

func (s *Store) Update(ctx context.Context, newOrUpdated, deleted []string) error

type StoreOption

type StoreOption func(*Store) error

func WithEnvFile

func WithEnvFile(specFile string, raw []byte) StoreOption

func WithEnvs

func WithEnvs(source string, envs ...string) StoreOption

func WithLogger

func WithLogger(logger *zap.Logger) StoreOption

func WithResolutionCRD

func WithResolutionCRD(raw []byte) StoreOption

func WithSpecDefsCRD

func WithSpecDefsCRD(raw []byte) StoreOption

func WithSpecFile

func WithSpecFile(specFile string, raw []byte) StoreOption

type TagFailedError

type TagFailedError struct {
	// contains filtered or unexported fields
}

func NewTagFailedError

func NewTagFailedError(varItem *SetVarItem, tag string, item string) *TagFailedError

func (TagFailedError) Code

func (TagFailedError) Error

func (e TagFailedError) Error() string

func (TagFailedError) Item

func (e TagFailedError) Item() string

func (TagFailedError) Key

func (e TagFailedError) Key() string

func (TagFailedError) Message

func (e TagFailedError) Message() string

func (TagFailedError) Source

func (e TagFailedError) Source() string

func (TagFailedError) SpecName

func (e TagFailedError) SpecName() string

func (TagFailedError) String

func (e TagFailedError) String() string

func (TagFailedError) Tag

func (e TagFailedError) Tag() string

func (TagFailedError) VarItem

func (e TagFailedError) VarItem() *SetVarItem

type ValidateErrorType

type ValidateErrorType uint8
const (
	ValidateErrorVarRequired ValidateErrorType = iota
	ValidateErrorTagFailed
	ValidateErrorResolutionFailed
)

type ValidationError

type ValidationError interface {
	fmt.Stringer
	VarItem() *SetVarItem
	Error() string
	Message() string
	Key() string
	SpecName() string
	Source() string
	Code() ValidateErrorType
}

todo(sebastian): perhaps this should be ValueError instead?

type ValidationErrors

type ValidationErrors []ValidationError

func TagValidator

func TagValidator(item *varSpec, itemKey string, varItem *SetVarItem) (ValidationErrors, error)

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL