config

package
v1.76.10 Latest Latest
Warning

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

Go to latest
Published: Oct 15, 2026 License: MIT Imports: 23 Imported by: 1

Documentation

Overview

Package config is sluis's configuration as a public, stable surface: the documents a process is started with, how to load and check them, and the installation document an estate writes once and renders them from.

An estate knows one thing about an installation (where it runs, which AWS resources and which OpenBao it is built on, whom it trusts, what its clients are) and sluis needs two documents of it: the service document (`sluis.yaml`, apiVersion sluis.truvity.github.io/sluis/v3) and the policy document (`policy.yaml`, .../policy/v2). The installation (apiVersion sluis.truvity.github.io/installation/v1, Installation) is the estate's side of that line and Render is sluis's: the same function `sluisctl render` runs, and the one the Pulumi library (github.com/truvity/sluis/deploy/pulumi) calls, so a Lambda estate and a Kubernetes estate write the documents the same way and neither hand-renders them.

in, err := config.LoadInstallation("installation.yaml")
service, policy, err := config.Render(in)

Render is deterministic (sorted keys, a fixed layout) and holds both outputs to the loader the service runs at start, so a document it returns is one the service accepts. Nothing here reads a secret: a document names each secret and the installation never carries a value.

The documents' own types are the binary's, re-exported: a field of one is reachable by value, and the types are held to their schemas (schemas/config/) by the tests of this repository. A key this package does not name is refused by the schema, never dropped.

Index

Constants

View Source
const (
	CloudflareStoreExternal = internal.CloudflareStoreExternal
	CloudflareStoreNone     = internal.CloudflareStoreNone
)

The values of a Cloudflare preset's `store`: `external` (the default) has the schedule rotate the preset into external/cloudflare/<preset>; `none` makes it on-demand only, with nothing stored.

View Source
const (
	// LambdaPolicyFile is the policy in the configuration layer.
	LambdaPolicyFile = "/opt/sluis/policy.yaml"
	// KubernetesPolicyFile is where the chart mounts the policy document.
	KubernetesPolicyFile = "/var/run/access-issuer/policy/policy.yaml"
	// ServerPolicyFile is the policy of a process on a host.
	ServerPolicyFile = "/etc/sluis/policy.yaml"
)

Where each shape finds the policy document, unless the installation says.

View Source
const (
	ModuleGitHub     = "github"
	ModuleSlack      = "slack"
	ModuleGoogle     = "google"
	ModuleCloudflare = "cloudflare"
	// ModuleIssuer names the issuer for [ModuleSecrets]; it has no entry in
	// [ModuleDocuments.Modules].
	ModuleIssuer = "issuer"
	// ModuleBackup names the backup function for [FunctionNameOf]; it has no
	// entry in [ModuleDocuments.Modules].
	ModuleBackup = "backup"
)

The modules a Lambda installation runs as functions of their own, by the name the installation's `aws.functions` and ModuleDocuments.Modules give them. The issuer is the other function, and its document is ModuleDocuments.Issuer.

View Source
const (
	// StateSecretName is the issuer's sign-in state secret.
	StateSecretName = "issuer/state-secret"
	// RecoveryPasswordName is the recovery password, where there is no cluster
	// to prove access to.
	RecoveryPasswordName = "recovery/password"
)

The names the layout gives the secrets sluis itself writes. They are fixed, so an installation never repeats them.

View Source
const CloudflareStoredRefPrefix = internal.CloudflareStoredRefPrefix

CloudflareStoredRefPrefix begins the address of the credential the Cloudflare module rotates for a preset with `store: external`: `external/cloudflare/<preset>`, which `ports.blob.s3.credentialsRef` may name.

View Source
const DefaultFunctionName = "sluis"

DefaultFunctionName is the Lambda function an installation that names none and has no instance is rendered for. With an instance the default is `sluis-<instance>-issuer`.

View Source
const EnvConfig = internal.EnvConfig

EnvConfig is the variable that names the service document when a process is given no --config.

View Source
const Group = internal.Group

Group is the group of the documents' kinds: an apiVersion is `<Group>/<document>/v<N>`.

View Source
const InstallationVersion = Group + "/installation/v1"

InstallationVersion is the apiVersion of the installation document.

View Source
const LiveAlias = "live"

LiveAlias is the alias of the Lambda function that every caller uses: the API, the schedules and a run-now. The Lambda shape's `invoke` trigger names `<function>:live`, so that a run-now runs the version the schedules run.

View Source
const ZipNameTemplate = "sluis-%s_%s_linux_arm64.zip"

ZipNameTemplate is the file name of a module's Lambda zip, `%s` being the module and the version following it: `sluis-<module>_<version>_linux_arm64.zip`. An estate pins one digest per zip, found in the release's checksums.txt under this name.

Variables

This section is empty.

Functions

func APIVersion

func APIVersion(document string) string

APIVersion is the apiVersion this build writes for one document: `sluis` (v3), `policy` (v2) or `installation` (v1).

func CheckInstallation added in v1.76.10

func CheckInstallation(existing []byte, in *Installation, opts MarshalOptions) (equal bool, diff string, err error)

CheckInstallation reports whether existing is what MarshalInstallation writes for in with opts. When it is not, diff is a line diff from existing (`-`) to the written document (`+`) with three lines of context. It returns an error, and no verdict, when the installation cannot be written.

It compares bytes, so a header the caller changed, or a hand edit that the loader reads the same, is a difference: that is what a `--check` mode is for.

func CloudflareStoredRef added in v1.76.8

func CloudflareStoredRef(ref string) (preset string, ok bool)

CloudflareStoredRef reports whether ref is a stored preset credential's address, and the preset it names.

func ConsoleAudience

func ConsoleAudience(in *Installation) string

ConsoleAudience is the audience an AWS role's web identity token is minted for to be a bearer at the console: `console.awsAudience`, else the console's URL (the service's own default).

func DefaultSignKeyAlias added in v1.74.0

func DefaultSignKeyAlias(instance string) string

DefaultSignKeyAlias is the alias of an installation's `keys.sign` key when the installation names none: the one the Pulumi library's grants are written for.

func FunctionNameOf added in v1.76.0

func FunctionNameOf(in *Installation, module string) string

FunctionNameOf is the name of a function: `aws.functions.<module>`, else `sluis-<instance>-<module>`. The module is one of Modules, ModuleIssuer (the issuer, whose name `aws.functionName` also sets, as it did before the default was `sluis-<instance>-issuer`; an installation with no instance is `sluis`, DefaultFunctionName) or ModuleBackup.

func InstallationSchema

func InstallationSchema() []byte

InstallationSchema is the authored schema of the installation document, the file schemas/config/installation.schema.json: the one `sluisctl render` holds a document to, and the one an estate's CI can validate against without this package.

func Load

func Load[T Document](file string) (*T, error)

Load reads one document from a file, holds it to its schema and decodes it. A v2 document is validated as it stands; an older one the binary still reads is converted. For the policy document the semantic checks run too.

func MarshalInstallation added in v1.76.10

func MarshalInstallation(in *Installation, opts MarshalOptions) ([]byte, error)

MarshalInstallation writes an installation as its canonical YAML document: the form a person reviews and `sluisctl render` reads.

The form is fixed. `apiVersion` is the first key; every other key, at every level, is sorted by name. The indent is two spaces, the style is block, and a duration is written as Go spells it with the zero trailing units dropped (`1h`, `15m`, `336h`, `1h30m`), never `1h0m0s`. A field that is unset, or zero, is left out; so is an empty list or map. A section that is set but empty (`controllers.github: {}` is a controller that is on) is kept, because leaving it out would turn it off.

The installation is refused when the loader would refuse the document, so a writer cannot produce a document that sluis will not start with: the document is held to the installation schema (ValidateInstallation), to the checks Render makes before it renders, and is decoded back into the types. An empty APIVersion is written as InstallationVersion.

The output is a function of the installation alone, and loading it gives an installation that writes the same bytes again.

func Modules added in v1.76.0

func Modules() []string

Modules are the module functions, in a fixed order.

func Render

func Render(in *Installation) (service, policy []byte, err error)

Render writes the two documents of an installation: the service document (`sluis.yaml`, sluis/v3) and the policy document (`policy.yaml`, policy/v2).

It is deterministic: the keys of both are sorted, `apiVersion` comes first, and nothing but the installation decides a byte of the output, so a renderer run twice, or by `sluisctl render` and by the Pulumi library, writes the same documents. It does not change in.

Render writes only what the installation says or the shape implies, and says in its error which key is wrong. Both outputs are then loaded by the loader the service runs at start (the schema, then the semantic checks), so a document Render returns is one the service accepts. What only a running process can check, such as an adapter that needs a platform answer the platform does not give, is still checked at start.

What the shape implies:

  • the preset, when none is named;
  • `policy.file`, `publicURL`, `publicRootURL` and `inCluster`;
  • the adapters the AWS resources and the OpenBao settings stand for, for each concern `adapters` does not name;
  • for shape lambda, the library-owned names: `secrets` (ssm, the instance's root), `recovery.passwordSecret`, and the `invoke` trigger's function; and for any signing by KMS, the state secret.

A value the installation writes that disagrees with what the shape fixes is an error, not a choice.

func SSMRoot

func SSMRoot(instance string) string

SSMRoot is the installation's secrets root: /sluis/<instance>.

func Validate

func Validate(name string, doc any) error

Validate checks a decoded document against its authored schema: name is `sluis`, `policy` or `installation`. The chart's tests call it on what the chart renders.

func ValidateInstallation

func ValidateInstallation(doc any) error

ValidateInstallation checks a decoded installation document (a generic YAML or JSON value) against the schema.

func ValidateModule added in v1.76.0

func ValidateModule(module string, doc, policy []byte) error

ValidateModule loads a module's service document as its function does: the schema, the decode and the checks a schema cannot make. policy, when given, is the policy document the Cloudflare module's grants are held to.

func ZipModules added in v1.76.0

func ZipModules() []string

ZipModules are the modules a release publishes a Lambda zip for, in a fixed order: the issuer, the module functions of Modules and backup (which is deployed twice, as the backup and the restore function). It is the one list the goreleaser configuration, the release lists and the Pulumi library's default package names are held to. There is no zip for the signer, the mint (the github function serves it) or restore.

func ZipName added in v1.76.0

func ZipName(module, version string) string

ZipName is the file name of the Lambda zip of module at version (no `v`).

func ZipPrefix added in v1.76.0

func ZipPrefix(module string) string

ZipPrefix is what a module's zip name starts with, up to the version.

Types

type AWS

type AWS struct {
	Account string `json:"account,omitempty"`
	Region  string `json:"region,omitempty"`
	// FunctionName is the Lambda function the `invoke` trigger names (through its `live` alias).
	// Unset is `sluis-<instance>-issuer`. Prefer Functions["issuer"]; this one is kept for
	// estates that already set it.
	FunctionName string `json:"functionName,omitempty"`
	// Functions name the functions by module (issuer, github, slack, google,
	// cloudflare, backup) when [RenderModules] is the renderer. Unset is
	// `sluis-<instance>-<module>`. The issuer's call to each names it
	// (`<module>.remote`).
	Functions map[string]string `json:"functions,omitempty"`
	// Table is the DynamoDB table of the `dynamodb` state adapter.
	Table string `json:"table,omitempty"`
	// Bucket is the S3 bucket of the `s3` blobs adapter.
	Bucket string `json:"bucket,omitempty"`
	// AuditQueueURL is the SQS queue of the `sqs` audit adapter.
	AuditQueueURL string `json:"auditQueueURL,omitempty"`
}

AWS is the account and the resources an installation is built on. Each resource becomes the setting of the adapter that uses it.

type AWSAccount

type AWSAccount struct {
	Account string   `json:"account"`
	Name    string   `json:"name"`
	Issuer  string   `json:"issuer"`
	JWKSURI string   `json:"jwksUri,omitempty"`
	OrgID   string   `json:"orgId,omitempty"`
	Algs    []string `json:"algs,omitempty"`
}

AWSAccount is one trusted account.

type Access

type Access struct{ policy.Policy }

Access is the access model's tables, as the policy document holds them.

func FromAccess added in v1.76.10

func FromAccess(access policy.Access, b Bootstrap) (Access, error)

FromAccess builds the installation's `access` section from an access document's derived part and the installation's bootstrap rows. It is the reshaping policy.AccessDocument.Policy does (lists to tables, camelCase to the policy's own keys) with the rows appended to their groups, and nothing else: no field of the access part is dropped, except the seven of a client that describe the relying party's own deployment and are read by whatever deploys it (policy.AccessClient).

The result is not validated as a policy; Render does that. FromAccess refuses a Bootstrap that is malformed, names a workload twice in one list, uses a group or client of its own that the access part also declares, or uses one name for two rows.

func (Access) MarshalJSON

func (a Access) MarshalJSON() ([]byte, error)

MarshalJSON writes the tables as the access model writes them.

func (*Access) UnmarshalJSON

func (a *Access) UnmarshalJSON(raw []byte) error

UnmarshalJSON reads the tables as the policy document does (JSON is YAML): through the access model's own strict parser.

type AdapterChoice

type AdapterChoice = internal.AdapterChoice

AdapterChoice names the adapter of one concern and its settings.

type AgentLifetimes added in v1.69.0

type AgentLifetimes = internal.AgentLifetimes

AgentLifetimes is `lifetimes.agent`: the agent session class's own.

type Apps

type Apps struct{ internal.PolicyApps }

Apps is what an operator may make on the console: the policy document's `apps`, under the same keys.

func (Apps) MarshalJSON

func (a Apps) MarshalJSON() ([]byte, error)

MarshalJSON writes the section under the keys the policy document gives it.

func (*Apps) UnmarshalJSON

func (a *Apps) UnmarshalJSON(raw []byte) error

UnmarshalJSON reads the section as the policy document does. The retired `runnerTiers` and `catalogue` of the GitHub section are read as entries of its `apps` list, with a warning.

type Audit

type Audit = internal.Audit

Audit is `audit`: the audit installation the service records to.

type Bootstrap added in v1.76.10

type Bootstrap struct {
	// Recovery is the account that holds the break-glass groups.
	Recovery *BootstrapRecovery
	// Viewers is the group of everyone who may look, and the people and
	// workloads it admits beside the matrix's own.
	Viewers *BootstrapViewers
	// Controllers are the workloads that run the directory controllers.
	Controllers *BootstrapControllers
	// Probe is the workload that proves the exchange.
	Probe *BootstrapProbe
	// GenerateSecrets writes every confidential client's secret as
	// `{generate: true}` and not as the name the access document gives. The
	// issuer then makes and keeps the value.
	GenerateSecrets bool
	// Claims is the claims table: what a group adds to a token. The access
	// document has no such table, so it is carried through unchanged.
	Claims map[string]policy.Fragment
}

Bootstrap is what an installation adds to the access model's derived part: how it is reached before a directory can vouch for anybody. Every row is typed and checked by FromAccess; a nil row adds nothing.

The rows fold into the groups the way an estate's own renderer has done it: matchers are appended after what the access matrix derived, in the order the fields below list them, and a group the matrix never produced is created with only these.

type BootstrapControllers added in v1.76.10

type BootstrapControllers struct {
	// Group is that group's name. It must not be a group of the access
	// matrix: a person placed there would be served as a controller.
	Group string
	// ServiceAccounts is the release's ServiceAccount on Kubernetes.
	ServiceAccounts []BootstrapServiceAccount
	// RoleARNs are the functions' roles on Lambda.
	RoleARNs []string
}

BootstrapControllers are the workloads of the GitHub and Slack controllers. They join the viewers, and, when Group is set, a group of their own that the console reads to serve them unrecorded and that grants no role.

type BootstrapProbe added in v1.76.10

type BootstrapProbe struct {
	// Group is the group the workload joins. It must not be a group of the
	// access matrix.
	Group string
	// Client is the exchange client, which requires Group. It must not be a
	// client of the access matrix.
	Client string
	// ServiceAccount is the probe's account. Its cluster is required.
	ServiceAccount BootstrapServiceAccount
}

BootstrapProbe is the workload that proves a token minted by another cluster is verified against the key set that cluster publishes. Its client is an exchange target that grants nothing.

type BootstrapRecovery added in v1.76.10

type BootstrapRecovery struct {
	ServiceAccount BootstrapServiceAccount
	// Groups are the groups the account joins, for example the operator
	// group and one cluster's auditor group. They may be groups of the
	// access matrix.
	Groups []string
}

BootstrapRecovery admits one ServiceAccount to each of the named groups. Where recovery is the password (Lambda) the row is left out.

type BootstrapServiceAccount added in v1.76.10

type BootstrapServiceAccount struct {
	// Cluster narrows the account to one named cluster. Empty matches any.
	Cluster string
	// Namespace and Name are the account's, both required.
	Namespace string
	Name      string
}

BootstrapServiceAccount is one Kubernetes ServiceAccount.

type BootstrapViewers added in v1.76.10

type BootstrapViewers struct {
	// Group is the group's name. It may be a group of the access matrix.
	Group string
	// EmailDomain admits every signed-in address of one domain.
	EmailDomain string
	// ServiceAccounts and RoleARNs are the workloads admitted besides the
	// controllers, which join the group on their own row.
	ServiceAccounts []BootstrapServiceAccount
	// RoleARNs are IAM roles, `arn:aws:iam::<account>:role/[path/]<name>`.
	RoleARNs []string
}

BootstrapViewers is the group that may look at the installation.

type Cloudflare added in v1.74.0

type Cloudflare struct {
	internal.Cloudflare
	// Grants say which group or CI job may ask for which preset.
	Grants []internal.CloudflareGrant `json:"grants,omitempty"`
}

Cloudflare is the service document's `cloudflare` section and, beside it, the grants the policy document's `cloudflare` holds.

func (*Cloudflare) AnyStored added in v1.76.7

func (c *Cloudflare) AnyStored() bool

AnyStored reports whether some declared preset is rotated by the schedule (`store` unset or `external`). The library schedules the rotation and grants the stored credentials only then: presets that are all `store: none` are minted on demand and nothing is kept for them.

func (*Cloudflare) Declared added in v1.74.0

func (c *Cloudflare) Declared() bool

Declared reports whether the installation declares any preset: the library then schedules the rotation and grants the function what it needs.

type CloudflareAccount added in v1.74.0

type CloudflareAccount = internal.CloudflareAccount

CloudflareAccount is one Cloudflare account and its minter credential's address.

type CloudflareGrant added in v1.74.0

type CloudflareGrant = internal.CloudflareGrant

CloudflareGrant opens presets to a group or a CI job.

type CloudflarePreset added in v1.74.0

type CloudflarePreset = internal.CloudflarePreset

CloudflarePreset is one thing sluis mints.

type CloudflareSection added in v1.74.0

type CloudflareSection = internal.Cloudflare

CloudflareSection is the service document's `cloudflare`: the accounts and presets. Cloudflare adds the policy's grants to it.

type Console

type Console = internal.Console

Console is `console`: where the console is published.

type Controllers

type Controllers struct {
	GitHub *GitHubController `json:"github,omitempty"`
	Slack  *SlackController  `json:"slack,omitempty"`
}

Controllers are the controllers the installation runs. A nil one is off.

type DeclaredSecret added in v1.75.0

type DeclaredSecret = internal.DeclaredSecret

DeclaredSecret is one secret the service document and the policy declare: the installation must hold it, and a deploy-time check looks for it. Name is where layout v4 keeps it below `internal/config/`; for a Ref (a Cloudflare minter, the S3 credentials document) it is the internal address the document gives, the same on every layout.

func DeclaredSecrets added in v1.75.0

func DeclaredSecrets(svc *Sluis, pol *PolicyDocument) []DeclaredSecret

DeclaredSecrets is the set of secrets svc and pol declare, sorted and without repeats; pol may be nil. It reads nothing, and no value is in it. It is what a deploy-time check (`{"kind":"check"}`, `sluis check`) looks for.

func ModuleSecrets added in v1.76.0

func ModuleSecrets(module string, doc, policy []byte) ([]DeclaredSecret, error)

ModuleSecrets are the secrets a module's function declares and checks, from its document: the kinds the function reads and no other module's. The GitHub and Slack modules declare none (an App's credential is made at run time), the Google module its workspaces' keys, the Cloudflare module its accounts' minters, and the issuer the rest (the recovery password, the state secret, the sign-in client, the policy's client secrets, the blob store's credential). The blob store's credential is the one both the issuer and the Google module read.

type Directory

type Directory = internal.Directory

Directory is `directory`: the corporate directories declared.

type Document

type Document = internal.Document

Document is what Load reads.

type Duration

type Duration = duration.Duration

Duration is a time span as a document spells it: "30s", "2m", "168h".

type Exchange

type Exchange struct {
	Audience string             `json:"audience,omitempty"`
	Clusters []FederatedCluster `json:"clusters,omitempty"`
	AWS      *FederatedAWS      `json:"aws,omitempty"`
	GitHub   *ExchangeGitHub    `json:"github,omitempty"`
}

Exchange is how the token exchange verifies workloads. Audience is the service document's; the rest is the policy document's `exchange`.

type ExchangeGitHub

type ExchangeGitHub struct {
	Owners []string `json:"owners,omitempty"`
}

ExchangeGitHub is whose GitHub Actions tokens are verified.

type FederatedAWS

type FederatedAWS struct {
	Audience string       `json:"audience,omitempty"`
	MaxAge   *Duration    `json:"maxAge,omitempty"`
	Accounts []AWSAccount `json:"accounts,omitempty"`
}

FederatedAWS is the AWS accounts whose roles' outbound identity tokens are verified.

type FederatedCluster

type FederatedCluster struct {
	Name    string `json:"name"`
	Issuer  string `json:"issuer"`
	JWKSURI string `json:"jwksUri,omitempty"`
}

FederatedCluster is one cluster whose ServiceAccount tokens are verified.

type Freshness

type Freshness = internal.Freshness

Freshness is `freshness`: how the directory's snapshot is kept current.

type GitHubController

type GitHubController struct {
	internal.GitHubController
	EnabledOrgs []string `json:"enabledOrgs,omitempty"`
	// AppRefs names, by organisation, the catalogue App whose key the
	// organisation's record refers to. Optional: an organisation that was
	// connected with an App of its own keeps naming it, so an entry is
	// needed only to name another App or to declare an organisation anew.
	AppRefs map[string]string `json:"appRefs,omitempty"`
	// AppNames names, by organisation, the App created for an organisation
	// the github table binds (at most 34 characters). Optional: an
	// organisation with no entry gets the built-in default.
	AppNames map[string]string `json:"appNames,omitempty"`
}

GitHubController is the GitHub controller: its own keys go to the service document's `controllers.github`, EnabledOrgs to the policy document's.

type Installation

type Installation struct {
	// APIVersion is [InstallationVersion].
	APIVersion string `json:"apiVersion"`
	// Instance is the installation's name (`acme`, `prod`). Its SSM root is
	// /sluis/<instance>.
	Instance string `json:"instance"`
	// Shape is where it runs.
	Shape Shape `json:"shape"`
	// Preset names the adapters of a whole platform. Unset follows the shape:
	// aws-hybrid (lambda), k8s-aws (kubernetes with `aws`), k8s-openbao
	// (kubernetes with `openbao`), k8s-minimal, server.
	Preset string `json:"preset,omitempty"`
	// Release is the name the installation's objects carry. Unset is `sluis`.
	Release string `json:"release,omitempty"`
	// Cluster names the cluster in a ServiceAccount's subject.
	Cluster string `json:"cluster,omitempty"`
	// PolicyFile is where the service finds the policy document. Unset follows
	// the shape.
	PolicyFile string `json:"policyFile,omitempty"`

	Issuer    Issuer     `json:"issuer"`
	Log       *Log       `json:"log,omitempty"`
	Lifetimes *Lifetimes `json:"lifetimes,omitempty"`
	Freshness *Freshness `json:"freshness,omitempty"`
	// Secrets is the service document's `secrets`, for a platform with no
	// secrets adapter of its own. Shape lambda fills it (ssm, the instance's
	// root) and refuses another value.
	Secrets *Secrets `json:"secrets,omitempty"`

	// AWS is the account and the resources the installation is built on.
	AWS *AWS `json:"aws,omitempty"`
	// OpenBao is the OpenBao the secrets are kept in.
	OpenBao *OpenBao `json:"openbao,omitempty"`
	// Adapters name single concerns over what the preset and the resources
	// above give.
	Adapters map[string]AdapterChoice `json:"adapters,omitempty"`

	// Keys says which key serves which purpose (the service document's
	// `keys`). With `signingKey.kmsWrapped` and no `keys`, the sign key is
	// alias/sluis-<instance>-sign on kms.
	Keys        *keys.Config `json:"keys,omitempty"`
	SigningKey  *SigningKey  `json:"signingKey,omitempty"`
	Recovery    *Recovery    `json:"recovery,omitempty"`
	Login       *Login       `json:"login,omitempty"`
	Console     *Console     `json:"console,omitempty"`
	OAuthClient *OAuthClient `json:"oauthClient,omitempty"`
	Valkey      *Valkey      `json:"valkey,omitempty"`
	Directory   *Directory   `json:"directory,omitempty"`
	Audit       *Audit       `json:"audit,omitempty"`
	// Cloudflare is sluis as the STS for Cloudflare tokens and R2 credentials:
	// the accounts and presets go to the service document's `cloudflare`, the
	// grants to the policy document's.
	Cloudflare *Cloudflare `json:"cloudflare,omitempty"`

	// Exchange is how the token exchange verifies workloads and whom it trusts.
	Exchange *Exchange `json:"exchange,omitempty"`
	// Apps is what an operator may make on the console.
	Apps *Apps `json:"apps,omitempty"`
	// Controllers are the controllers that run, and what each may change.
	Controllers *Controllers `json:"controllers,omitempty"`
	// Access is the access model's tables: groups, clients, resources and the
	// GitHub and Slack bindings.
	Access *Access `json:"access,omitempty"`
}

Installation is everything an estate knows about one installation of sluis. It is a superset of the service document and the policy document: a section is under the key the document gives it (the types are the documents' own), and the installation adds what a document cannot say, which is the shape it runs in and the AWS and OpenBao resources it is built on. Render splits it into the two documents.

It holds no secret. A document names each secret, and where the names are read from is `secrets` or the secrets adapter.

func LoadInstallation

func LoadInstallation(file string) (*Installation, error)

LoadInstallation reads an installation document from a file and holds it to its schema.

func (*Installation) String

func (in *Installation) String() string

String names the installation without printing any of it.

type Issuer

type Issuer struct {
	// URL is the issuer (`issuerURL`).
	URL string `json:"url"`
	// ConsoleURL is `publicURL`. Unset is URL plus /console.
	ConsoleURL string `json:"consoleURL,omitempty"`
	// RootURL is `publicRootURL`. Unset is URL.
	RootURL string `json:"rootURL,omitempty"`
	// SecureCookies is `secureCookies`.
	SecureCookies *bool `json:"secureCookies,omitempty"`
	// GroupsScoping is `groupsScoping`: off, report or enforce.
	GroupsScoping string `json:"groupsScoping,omitempty"`
}

Issuer is the issuer and where a browser reaches the console.

type Lifetimes

type Lifetimes = internal.Lifetimes

Lifetimes is `lifetimes`: how long what the issuer hands out lives.

type Log

type Log = internal.Log

Log is `log`.

type Login

type Login = internal.Login

Login is `login`: how a person signs in to the console.

type MarshalOptions added in v1.76.10

type MarshalOptions struct {
	// Header is a comment block written before the document. Each line is
	// written as a YAML comment (`# ` is added to a line that does not start
	// with `#`), and the block ends with a line break. The caller owns its
	// text; it is not part of the document and the loader ignores it.
	Header string
}

MarshalOptions are the caller's choices for MarshalInstallation.

type ModuleDocuments added in v1.76.0

type ModuleDocuments struct {
	// Issuer is the issuer's service document (sluis/v3): [Render]'s with the
	// modules it calls elsewhere, `github.remote`, `slack.remote`, `google.remote`
	// and `cloudflare.remote`, naming the functions; what the modules own
	// (`controllers`, `directory`, the Cloudflare accounts and presets) is not in it.
	Issuer []byte
	// Policy is the policy document (policy/v2) every function that decides by
	// it reads from the same file.
	Policy []byte
	// Modules are the service documents of the module functions, by
	// [Modules]: controller-github/v2, controller-slack/v2, sluis-google/v1 and sluis/v3 with `cloudflare.serve`. The Cloudflare module has one only when
	// the installation declares a preset: a module with nothing to do has no
	// function.
	Modules map[string][]byte
}

ModuleDocuments are the documents of a Lambda installation that runs a function per module.

func RenderModules added in v1.76.0

func RenderModules(in *Installation, opts ModuleOptions) (*ModuleDocuments, error)

RenderModules writes the documents of an installation that runs a function per module: Render's two documents, with the issuer's calling the modules by their functions, and a service document for each module that holds what is the module's own and nothing else.

A module document opens only its own table (`ports.dynamodb.tables` has the module's alone, since the readiness probe describes each table it lists), reads its secrets as layout v5 (`secrets.layout: v5`), and names the same policy file as the issuer's, where the module reads one. The documents hold no secret, and the secrets they name are disjoint but for the blob store's credential (see ModuleSecrets).

It is deterministic and leaves in alone. Every document it returns has been loaded as the module's function loads it.

type ModuleOptions added in v1.76.0

type ModuleOptions struct {
	// Tables are the DynamoDB table of each module of layout v5, by the module's
	// name (oidc, github, slack, cloudflare, google, backup). A module not listed
	// has `sluis-<instance>-<module>`.
	Tables map[string]string
}

ModuleOptions say what an installation cannot: the names the infrastructure gave.

type OAuthClient

type OAuthClient = internal.OAuthClient

OAuthClient is `oauthClient`: the client registered with the directory backend.

type OpenBao

type OpenBao struct {
	Address   string       `json:"address"`
	CAFile    string       `json:"caFile,omitempty"`
	Mount     string       `json:"mount,omitempty"`
	Namespace string       `json:"namespace,omitempty"`
	Root      string       `json:"root"`
	Auth      OpenBaoLogin `json:"auth"`
}

OpenBao is the OpenBao the secrets are kept in: the settings of the `openbao` secrets adapter.

type OpenBaoLogin

type OpenBaoLogin struct {
	Method    string `json:"method"`
	Mount     string `json:"mount,omitempty"`
	Role      string `json:"role"`
	TokenFile string `json:"tokenFile,omitempty"`
}

OpenBaoLogin is how the service logs in to the OpenBao.

type Policy

type Policy = policy.Policy

Policy is the access model's tables, which a policy document holds.

type PolicyDocument

type PolicyDocument = internal.PolicyDocument

PolicyDocument is the policy document (v2): the access model's tables and whom the exchange trusts, what an operator may make, what each controller may change and what is copied out.

func RenderPolicyLayers

func RenderPolicyLayers(path string) (*PolicyDocument, error)

RenderPolicyLayers builds the one canonical policy document from a file or a directory of layers (a v1 policy file, an access document, or a policy document fragment), merged in name order and held to every check the service runs at start. It is what `sluisctl policy render` runs; an estate that writes an Installation has no layers to merge and calls Render.

type Recovery

type Recovery = internal.Recovery

Recovery is `recovery`: the sign-in that needs no directory.

type Secrets

type Secrets = internal.Secrets

Secrets is `secrets`: how the secrets a document names are delivered.

type Shape

type Shape string

Shape is where an installation runs.

const (
	// ShapeLambda is one AWS Lambda function behind an HTTP API; the documents
	// are an immutable configuration layer mounted at /opt/sluis.
	ShapeLambda Shape = "lambda"
	// ShapeKubernetes is one Deployment; the chart mounts the documents.
	ShapeKubernetes Shape = "kubernetes"
	// ShapeServer is one process on a host.
	ShapeServer Shape = "server"
)

The shapes.

type SigningKey

type SigningKey = internal.SigningKey

SigningKey is `signingKey`: where the issuer's keys are and how they rotate.

type SlackController

type SlackController struct {
	internal.SlackController
	EnabledWorkspaces []string `json:"enabledWorkspaces,omitempty"`
}

SlackController is GitHubController for Slack.

type Sluis

type Sluis = internal.Sluis

Sluis is the one service document (v3): the issuer, the console, the directory hub and, under `controllers`, the controllers the process runs.

type Valkey

type Valkey = internal.Valkey

Valkey is `valkey`: the shared store for logins in progress.

Jump to

Keyboard shortcuts

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