Chart values¶
Every value of the sluis chart (charts/sluis) with its default, held to charts/sluis/values.schema.json. The config.* keys are in Configuration; the model is in Configuration: the model.
| Included (standard Kubernetes APIs) | Expected to exist |
|---|---|
A Deployment, Service and ServiceAccount per module (the issuer, and each enabled modules.<m>), a HorizontalPodAutoscaler and a PodDisruptionBudget where set, cert-manager Certificates for the signing key and the route, a namespaced Role/RoleBinding (with the Kubernetes store), a cluster-scoped TokenReview role (with recovery), NetworkPolicy, the policy document and the service document as ConfigMaps, a Gateway and two HTTPRoutes (one for the issuer's own endpoints, one for the console's path), and, only where a push block is written, External Secrets PushSecrets; with backup.enabled, a CronJob each for the backup and the prune and an account of their own; with restore.enabled, one Job and an account of its own; with renders: alerts, a VMRule or PrometheusRule; with renders: dashboards, a grafana-operator GrafanaFolder and GrafanaDashboards |
cert-manager when the chart makes a Certificate, the grafana-operator or the rule operator for renders: dashboards or alerts, the Secrets a declared workspace, a declared OAuth client or an externally delivered signing key name; a Valkey, when config.valkey is set; External Secrets and the store each push block names |
Values¶
Source: charts/sluis/values.schema.json. Generated by just docs-generate; keys are listed with their parents first.
| Key | Type | Default | Meaning |
|---|---|---|---|
adapters |
object | — | What the chart mounts for the service's OpenBao connection (the openbao secrets adapter): the CA that signs OpenBao's certificate and the projected token the login presents. The address and how the service logs in are the config's (config.adapters.secrets). |
adapters.openbao |
object | — | |
adapters.openbao.caBundle |
string | — | PEM of the authorities that sign OpenBao's certificate. Rendered into a ConfigMap and mounted at /var/run/access-issuer/openbao-ca/ca.pem, which config.adapters.secrets.settings.caFile (the openbao Secrets adapter) must then be. Empty mounts nothing, and the system's authorities are trusted. |
adapters.openbao.token |
object | — | |
adapters.openbao.token.audience |
string | — | The audience of a ServiceAccount token the chart projects at /var/run/openbao/token, for the jwt auth method (config.adapters.secrets.settings.auth.tokenFile must then be that path). Empty projects nothing: the kubernetes method reads the pod's own ServiceAccount token. |
adapters.openbao.token.expirationSeconds |
integer | — | |
alerts |
object | — | Alert rules, rendered with renders: alerts. |
alerts.clusterLabel |
string | — | The label that names the cluster on a store that holds several. |
alerts.format |
one of vmrule, prometheusrule | — | The kind of object. |
alerts.interval |
string | — | How often the ruler evaluates the group. |
alerts.labels |
object | — | Labels on the rule object. |
alerts.labels.<name> |
string | — | |
alerts.name |
string | — | The object's name. Empty: |
alerts.namespace |
string | — | The namespace sluis runs in, whose series the rules read. Empty: the release's. |
alerts.namespaceLabel |
string | — | The label that carries the namespace on the series the rules read: namespace (the default), or k8s_namespace_name where the gateway keeps the resource's own. |
alerts.objectNamespace |
string | — | Where the rule object goes. Empty: the release's namespace. |
alerts.ruleLabels |
object | — | Labels added to every rule, for Alertmanager routing, such as k8s_cluster_name. |
alerts.ruleLabels.<name> |
string | — | |
alerts.rules |
object | — | The rules. |
alerts.rules.cloudflareRotationStale |
object | — | A Cloudflare preset's stored credential has not been rotated for more than twice its rotation. |
alerts.rules.cloudflareRotationStale.enabled |
boolean | — | |
alerts.rules.cloudflareRotationStale.factor |
number | — | How many rotations old the stored credential may be before the alert fires. |
alerts.rules.cloudflareRotationStale.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.cloudflareRotationStale.labels |
object | — | Labels added to this rule only. |
alerts.rules.cloudflareRotationStale.labels.<name> |
string | — | |
alerts.rules.cloudflareRotationStale.severity |
string | — | The severity label. |
alerts.rules.issuer5xx |
object | — | The listener answers a share of its requests 5xx. |
alerts.rules.issuer5xx.enabled |
boolean | — | |
alerts.rules.issuer5xx.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.issuer5xx.labels |
object | — | Labels added to this rule only. |
alerts.rules.issuer5xx.labels.<name> |
string | — | |
alerts.rules.issuer5xx.minErrors |
integer | — | The fewest 5xx in the window that count. |
alerts.rules.issuer5xx.ratio |
number | — | The share. |
alerts.rules.issuer5xx.severity |
string | — | The severity label. |
alerts.rules.leaseLost |
object | — | Tick leases are lost repeatedly. |
alerts.rules.leaseLost.enabled |
boolean | — | |
alerts.rules.leaseLost.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.leaseLost.labels |
object | — | Labels added to this rule only. |
alerts.rules.leaseLost.labels.<name> |
string | — | |
alerts.rules.leaseLost.losses |
integer | — | Leases lost within window by one kind of target. |
alerts.rules.leaseLost.severity |
string | — | The severity label. |
alerts.rules.leaseLost.window |
string | — | The window, as a duration. |
alerts.rules.noSigningKey |
object | — | No signing key is published. |
alerts.rules.noSigningKey.enabled |
boolean | — | |
alerts.rules.noSigningKey.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.noSigningKey.labels |
object | — | Labels added to this rule only. |
alerts.rules.noSigningKey.labels.<name> |
string | — | |
alerts.rules.noSigningKey.severity |
string | — | The severity label. |
alerts.rules.portErrors |
object | — | Storage port calls are failing. |
alerts.rules.portErrors.enabled |
boolean | — | |
alerts.rules.portErrors.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.portErrors.labels |
object | — | Labels added to this rule only. |
alerts.rules.portErrors.labels.<name> |
string | — | |
alerts.rules.portErrors.minErrors |
integer | — | The fewest failures in the window that count. |
alerts.rules.portErrors.ratio |
number | — | The share of calls that failed. |
alerts.rules.portErrors.severity |
string | — | The severity label. |
alerts.rules.rateLimitLow |
object | — | GitHub's rate-limit budget is nearly spent. |
alerts.rules.rateLimitLow.enabled |
boolean | — | |
alerts.rules.rateLimitLow.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.rateLimitLow.labels |
object | — | Labels added to this rule only. |
alerts.rules.rateLimitLow.labels.<name> |
string | — | |
alerts.rules.rateLimitLow.remaining |
integer | — | Requests left under which the alert fires. |
alerts.rules.rateLimitLow.severity |
string | — | The severity label. |
alerts.rules.seatsShort |
object | — | An organisation has fewer free seats than invitations. |
alerts.rules.seatsShort.enabled |
boolean | — | |
alerts.rules.seatsShort.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.seatsShort.labels |
object | — | Labels added to this rule only. |
alerts.rules.seatsShort.labels.<name> |
string | — | |
alerts.rules.seatsShort.severity |
string | — | The severity label. |
alerts.rules.signingKeyRotationStalled |
object | — | The active signing key is older than maxAgeSeconds. |
alerts.rules.signingKeyRotationStalled.enabled |
boolean | — | |
alerts.rules.signingKeyRotationStalled.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.signingKeyRotationStalled.labels |
object | — | Labels added to this rule only. |
alerts.rules.signingKeyRotationStalled.labels.<name> |
string | — | |
alerts.rules.signingKeyRotationStalled.maxAgeSeconds |
integer | — | The age, in seconds. |
alerts.rules.signingKeyRotationStalled.severity |
string | — | The severity label. |
alerts.rules.tickFailing |
object | — | A target's ticks keep failing. |
alerts.rules.tickFailing.enabled |
boolean | — | |
alerts.rules.tickFailing.failures |
integer | — | Failed ticks of one target within window. |
alerts.rules.tickFailing.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.tickFailing.labels |
object | — | Labels added to this rule only. |
alerts.rules.tickFailing.labels.<name> |
string | — | |
alerts.rules.tickFailing.severity |
string | — | The severity label. |
alerts.rules.tickFailing.window |
string | — | The window, as a duration. |
alerts.rules.tickSeriesStale |
object | — | A target's series stopped reporting. |
alerts.rules.tickSeriesStale.enabled |
boolean | — | |
alerts.rules.tickSeriesStale.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.tickSeriesStale.labels |
object | — | Labels added to this rule only. |
alerts.rules.tickSeriesStale.labels.<name> |
string | — | |
alerts.rules.tickSeriesStale.severity |
string | — | The severity label. |
alerts.rules.tickStale |
object | — | A target has had no ok tick for maxAgeSeconds. |
alerts.rules.tickStale.enabled |
boolean | — | |
alerts.rules.tickStale.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.tickStale.labels |
object | — | Labels added to this rule only. |
alerts.rules.tickStale.labels.<name> |
string | — | |
alerts.rules.tickStale.liveWindow |
string | — | The age of the newest sample that makes a target live. |
alerts.rules.tickStale.maxAgeSeconds |
integer | — | The age, in seconds. |
alerts.rules.tickStale.severity |
string | — | The severity label. |
alerts.rules.tokenLatency |
object | — | The token endpoint's p99, Cloudflare mints apart, is over thresholdSeconds. |
alerts.rules.tokenLatency.enabled |
boolean | — | |
alerts.rules.tokenLatency.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.tokenLatency.labels |
object | — | Labels added to this rule only. |
alerts.rules.tokenLatency.labels.<name> |
string | — | |
alerts.rules.tokenLatency.minRequests |
integer | — | The fewest requests in the window that count: below 100, a p99 is the slowest request. |
alerts.rules.tokenLatency.severity |
string | — | The severity label. |
alerts.rules.tokenLatency.thresholdSeconds |
number | — | The p99, in seconds. |
alerts.rules.tokenLatency.window |
string | — | The window of the quantile and of the request count, as a duration. |
alerts.rules.tokenMintLatency |
object | — | The p95 of the token endpoint's Cloudflare mints is over thresholdSeconds. |
alerts.rules.tokenMintLatency.enabled |
boolean | — | |
alerts.rules.tokenMintLatency.for |
string | — | How long the condition holds before the alert fires, as a duration. |
alerts.rules.tokenMintLatency.labels |
object | — | Labels added to this rule only. |
alerts.rules.tokenMintLatency.labels.<name> |
string | — | |
alerts.rules.tokenMintLatency.minRequests |
integer | — | The fewest mints in the window that count. |
alerts.rules.tokenMintLatency.severity |
string | — | The severity label. |
alerts.rules.tokenMintLatency.thresholdSeconds |
number | — | The p95, in seconds. |
alerts.rules.tokenMintLatency.window |
string | — | The window of the quantile and of the request count, as a duration. |
alerts.runbookBaseUrl |
string | — | Where the runbook is; the alert's name, lower-cased, is the anchor. Empty renders no link. |
alerts.selector |
string | — | Extra matchers for every series. |
audit |
object | — | The projected service-account token this service and the controllers present to the audit installation. The installation itself (audit.writer and the rest) is the config's. |
audit.token |
object | — | |
audit.token.audience |
string | — | The audience of the projected token presented to the receiver. |
audit.token.expirationSeconds |
integer | — | |
backup |
object | — | The backup module (docs/reference/sluis/backup.md): a CronJob that runs sluis backup run, an optional CronJob that prunes by the retention rule, and the document they read. Layout v5 only. Off by default. The restore Job (restore) reads the same document. |
backup.activeDeadlineSeconds |
integer | 0 |
Stops a run after this many seconds. 0: no limit. |
backup.concurrencyPolicy |
one of Forbid, Replace, Allow | "Forbid" |
The run takes a lease, so two at once would only wait on it: Forbid. |
backup.config |
object | — | The backup module's document (backup.role backup; the restore Job runs the same document in the restore role), without its apiVersion, which the chart writes: rendered as it stands into the ConfigMap |
backup.config.adapters |
object | — | Names the adapter of single concerns, over the preset and the ports keys. The names and what each needs are in the matrix of docs/reference/sluis/adapters.md. |
backup.config.adapters.audit |
object | — | The adapter for the audit sink, replacing the preset's. |
backup.config.adapters.audit.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.audit.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.adapters.blobs |
object | — | The adapter for blobs, replacing the preset's. |
backup.config.adapters.blobs.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.blobs.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.adapters.schedule |
object | — | The adapter for the schedule of passes, replacing the preset's. |
backup.config.adapters.schedule.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.schedule.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.adapters.secrets |
object | — | The adapter for secrets (dynamic secrets), replacing the preset's. |
backup.config.adapters.secrets.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.secrets.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.adapters.signing |
object | — | The adapter for token signing, replacing the preset's. |
backup.config.adapters.signing.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.signing.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.adapters.state |
object | — | The adapter for state, sessions included, replacing the preset's. |
backup.config.adapters.state.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.state.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.adapters.trigger |
object | — | The adapter for the "run a pass now" trigger, replacing the preset's. |
backup.config.adapters.trigger.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
backup.config.adapters.trigger.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
backup.config.audit |
object | — | The audit installation this service records to. Unset keeps the trail in the log only. |
backup.config.audit.audience |
string | "audit" |
The client whose audience the Audit page's tokens carry. |
backup.config.audit.forwardedForTrustedHops |
integer | 0 |
How many of the deployment's own proxies append to X-Forwarded-For; zero records the peer. |
backup.config.audit.queryURL |
string | — | The query service, for the console's Audit page. Its own setting: it needs no writer, so the page works with the sqs and log sinks. A path prefix (https://audit.example/sluis) is kept and the procedure path appended. |
backup.config.audit.tokenFile |
string | — | This workload's projected service-account token, presented on every call. |
backup.config.audit.writer |
string | — | The installation's receiver. |
backup.config.backup |
object | — | What the backup module writes and where. The module reads every module's table, secrets and blobs through the ports and secrets above (its role has read access to them), and writes one age-encrypted tar.gz per backup, then its sidecar, to target (format 2, docs/reference/sluis/backup.md). |
backup.config.backup.identity |
string | "restore-identity" |
The restore role's secret holding the age identity (AGE-SECRET-KEY-1...) that decrypts the backups: internal/backup/ |
backup.config.backup.key |
any | — | Deprecated, ignored: the KMS key of backup format 1. Accepted for one release so a document that still sets it loads; set recipients. |
backup.config.backup.key.context |
any | — | The encryption context: "default" sends {instance, purpose}; "off" sends none; an object is sent as is. |
backup.config.backup.key.key |
string | — | An alias such as alias/sluis- |
backup.config.backup.recipients |
array | — | The age X25519 public keys (age1...) every backup is encrypted to; at least one, and required in the backup role. Each holder of a matching identity can decrypt a backup without sluis: age -d -i key.txt <id>.tar.gz.age \| tar xz. The backup role holds nothing that decrypts. In the restore role they are the recipients a backup's sidecar must list: a backup written to another set (before the recipients changed) is refused whatever else is passed, and an allowUnverified restore needs them. This does not detect a forged backup: the recipients are public. |
backup.config.backup.region |
string | — | Deprecated, ignored: the region of the KMS key of backup format 1. |
backup.config.backup.retention |
object | — | Which completed backups a prune keeps. A backup is deleted when it is beyond the keep newest AND older than maxAge. |
backup.config.backup.retention.keep |
integer | 7 |
How many of the newest completed backups are always kept. |
backup.config.backup.retention.maxAge |
string | "720h" |
How old a backup beyond keep may be before it is deleted. 0s deletes it as soon as it is beyond keep. |
backup.config.backup.role |
one of backup, restore | "backup" |
Which function this document configures: backup (the scheduled export, the default) or restore (the restore function, which only an administrator or the break-glass role may invoke and whose role may write every module's table). The zip is the same; the document picks the role, and sluis restore selects it on the command line. |
backup.config.backup.target |
object | required | The S3 bucket of the archive. For an AWS bucket with Object Lock, enable versioning and a default retention no longer than retention; credentials are the function role's and are never configured here. |
backup.config.backup.target.bucket |
string | required | The bucket. It must exist. |
backup.config.backup.target.checksum |
one of sha256, md5, none | "sha256" |
The integrity header of every upload: sha256 (x-amz-checksum-sha256, computed over the whole body and sent precomputed, never as an aws-chunked trailer), md5 (Content-MD5) or none, for a store that refuses SHA-256. AWS refuses a PutObject without one on an Object Lock bucket. |
backup.config.backup.target.endpoint |
string | — | Overrides the S3 address: LocalStack or an S3-compatible store. |
backup.config.backup.target.kmsKey |
string | — | A KMS key id, ARN or alias for server-side encryption of every write. Unset leaves the bucket's own default encryption. |
backup.config.backup.target.pathStyle |
boolean | — | Addresses the bucket in the path and not the host name, which LocalStack and most S3-compatible stores need. |
backup.config.backup.target.prefix |
string | — | A key prefix inside the bucket, put before backup/<instance>/. |
backup.config.backup.target.region |
string | — | The bucket's region. Unset follows the SDK's own resolution. |
backup.config.backup.verify |
object | — | How the restore role proves a backup is the one the backup function made, before it decrypts a byte (docs/reference/sluis/backup.md). Each completed backup is recorded in the audit trail with the hashes of its object and sidecar and its recipients; the restore asks the audit installation's query service for that record and requires the hashes to match and the hour to be sealed. Unset, the restore refuses every backup unless it is started with allowUnverified. Read by the restore role only. |
backup.config.backup.verify.anyObserver |
boolean | — | Accept a record stamped by any observer. Weakens the check to whoever may write a record as the roster source; a start logs a warning. One of observer and anyObserver is required. |
backup.config.backup.verify.observer |
string | — | The id the audit writer stamps on the backup function's records (the writer's senders table). A record of a backup stamped by any other is refused. Required unless anyObserver is set: without it, any principal that may send to the audit queue can plant a record that vouches for a forged backup. |
backup.config.backup.verify.profile |
string | — | The audit profile that keeps the activity category, where roster.backup.completed is kept. Default activity. |
backup.config.backup.verify.query |
string | required | The audit installation's query service (its address, without the /audit.v1.QueryService/... path). https, or http on a loopback address. |
backup.config.backup.verify.tokenFile |
string | required | A file holding the bearer token the query service accepts, read on every request. The token's grants must let it search and get on profile. |
backup.config.instance |
string | — | The installation's name, bound into the default encryption context of keys ({instance, purpose}): stable and not secret, because a ciphertext made under it opens only with it. Unset is release. |
backup.config.keys |
object | — | Which key serves which purpose. Keys are named by alias (KMS) or by name (transit), never by ARN or key id. See the package documentation of github.com/truvity/sluis/storage/keys. |
backup.config.keys.adapter |
one of kms, local, transit | required | The key service. |
backup.config.keys.archive |
any | — | Deprecated, ignored: the archive key of backup format 1. Accepted so a document that still sets it loads; backups are age-encrypted to backup.recipients. |
backup.config.keys.archive.context |
any | — | The encryption context: "default" sends {instance, purpose}; "off" sends none; an object is sent as is. |
backup.config.keys.archive.key |
string | — | An alias such as alias/sluis- |
backup.config.keys.conceal |
any | — | Values that must be recoverable. |
backup.config.keys.conceal.context |
any | — | The encryption context: "default" sends {instance, purpose}; "off" sends none; an object is sent as is. |
backup.config.keys.conceal.key |
string | — | An alias such as alias/sluis- |
backup.config.keys.pseudonym |
any | — | Per-tenant pseudonyms. |
backup.config.keys.pseudonym.context |
any | — | The encryption context: "default" sends {instance, purpose}; "off" sends none; an object is sent as is. |
backup.config.keys.pseudonym.key |
string | — | An alias such as alias/sluis- |
backup.config.keys.seal |
any | — | Sealing the audit trail. |
backup.config.keys.seal.context |
any | — | The encryption context: "default" sends {instance, purpose}; "off" sends none; an object is sent as is. |
backup.config.keys.seal.key |
string | — | An alias such as alias/sluis- |
backup.config.keys.sign |
any | — | Token signing: the symmetric key that wraps a locally generated signing ring, or an asymmetric key that signs directly (deprecated). |
backup.config.keys.sign.context |
any | — | The encryption context: "default" sends {instance, purpose}; "off" sends none; an object is sent as is. |
backup.config.keys.sign.key |
string | — | An alias such as alias/sluis- |
backup.config.log |
object | — | Structured logging. One level for the whole service: per-package levels are deliberately not part of the contract. |
backup.config.log.level |
one of debug, info, warn, error | "info" |
The lowest level that is written. |
backup.config.platform |
object | — | What this installation has to build on. The answers pick a preset (the decision tree in docs/concepts/sluis/ports.md), and start refuses an adapter that needs an answer that is no. Absent, the ports keys decide and nothing is checked against the platform. |
backup.config.platform.aws |
boolean | — | AWS is available: its credentials, DynamoDB, S3, SSM, KMS, SQS and EventBridge. |
backup.config.platform.kubernetes |
boolean | — | A Kubernetes cluster is available. |
backup.config.platform.openbao |
boolean | — | An OpenBao is available. |
backup.config.platform.replicas |
integer | 1 |
How many replicas share this installation's state. Above 1 start refuses an adapter that keeps its data in the process (memory). |
backup.config.platform.runtime |
one of kubernetes, lambda, process | — | Where sluis itself runs. Absent: kubernetes with a cluster, else lambda on AWS, else process. |
backup.config.ports |
object | — | The adapters behind the storage ports (docs/concepts/sluis/ports.md). |
backup.config.ports.adapter |
one of legacy, memory, dynamodb | "legacy" |
legacy, the default, is deprecated since v1.74.0 and still ships: migrate with sluis migrate. It keeps state where it has always been kept: the namespace's ConfigMaps and Secrets and, when valkey is set, Valkey. memory keeps all of it in this process, which a restart loses: for a local run and the demonstration, and not with store: kubernetes or valkey. dynamodb keeps the same in one DynamoDB table (ports.dynamodb), with the platform's credentials, and takes its Blob from legacy unless ports.blob names its own. |
backup.config.ports.blob |
object | — | Replaces the Blob port (status reports, directory snapshots) with an adapter of its own, whatever ports.adapter is. Absent, the Blob is ports.adapter's. |
backup.config.ports.blob.adapter |
one of s3 | required | s3 keeps the blobs in an S3 bucket. |
backup.config.ports.blob.s3 |
object | — | Where the S3 adapter keeps its objects. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here. |
backup.config.ports.blob.s3.bucket |
string | required | The bucket. It must exist, with public access blocked. |
backup.config.ports.blob.s3.checksum |
one of sha256, md5, none | "sha256" |
The integrity header of every upload: sha256 (x-amz-checksum-sha256, computed over the whole body and sent precomputed, never as an aws-chunked trailer), md5 (Content-MD5) or none, for a store that refuses SHA-256. AWS refuses a PutObject without one on an Object Lock bucket. |
backup.config.ports.blob.s3.credentials |
object | — | Instead of a static document, sluis mints its own R2 credentials from a Cloudflare preset: the account's minter credential clones the preset's prototype, the credentials are renewed with a third of their lifetime left and minted again once after a 403. Exclusive with credentialsRef. Needs endpoint, the ssm secrets source, and the cloudflare section. |
backup.config.ports.blob.s3.credentials.preset |
string | required | A key of cloudflare.presets that has an endpoint (an R2 preset). |
backup.config.ports.blob.s3.credentialsRef |
string | — | Where the credentials for endpoint are, in the installation's secrets store (the ssm secrets source): the internal address, internal/<module>/<name>, of the s3-credentials/v1 document (access_key_id, secret_access_key) that holds static credentials, or external/cloudflare/<preset>, the cloudflare/v1 document the Cloudflare module rotates for an R2 preset with store: external (the access key is the token's id; it is read again with a third of its time left and after a 403). Read at start and again after an answer of 403, at most once a minute. Needs endpoint; region defaults to auto with it. Any other address is refused. This is the simple way and needs no cloudflare section in this document, so it is the one to use when the presets are another module's (cloudflare.remote). |
backup.config.ports.blob.s3.endpoint |
string | — | Overrides the S3 address: LocalStack or an S3-compatible store (Cloudflare R2, MinIO). |
backup.config.ports.blob.s3.kmsKey |
string | — | A KMS key id, ARN or alias for server-side encryption (SSE-KMS) of every write. Absent, the bucket's default encryption applies. |
backup.config.ports.blob.s3.pathStyle |
boolean | — | Addresses the bucket in the path and not the host name, which LocalStack and most S3-compatible stores need. |
backup.config.ports.blob.s3.prefix |
string | — | A key prefix inside the bucket, for an installation that shares it. |
backup.config.ports.blob.s3.region |
string | — | The bucket's region. Absent, the SDK's own resolution (AWS_REGION). |
backup.config.ports.dynamodb |
object | — | The DynamoDB tables of the dynamodb adapter: one table per module (tables, layout v5). Each has a string partition key pk, a string sort key sk and the TTL attribute expires. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here; an S3-compatible endpoint with no such identity names a credentials document by address (credentialsRef), never by value. |
backup.config.ports.dynamodb.create |
boolean | false |
Create the table (on-demand, TTL on expires) at start when it is not there, for a test or a development installation. Off, the table must exist: production uses the one the infrastructure code made, and the role needs dynamodb:DescribeTable on it (layout v5: the readiness probe asks, not the start). |
backup.config.ports.dynamodb.endpoint |
string | — | Overrides the DynamoDB address: LocalStack or DynamoDB Local. |
backup.config.ports.dynamodb.region |
string | — | The table's region. Absent, the SDK's own resolution (AWS_REGION). |
backup.config.ports.dynamodb.tables |
object | required | Layout v5 (docs/decisions/0072-storage-layout-v5-module-first.md): the table of each module, by module name. A process names its own module's table and the tables of the peers it reads; a module it does not name is not opened. The single table of layout v4 (table) was removed in v1.77.1. |
backup.config.ports.dynamodb.tables.backup |
string | — | The name of the backup module's table. The library default is sluis-<instance>-backup. |
backup.config.ports.dynamodb.tables.cloudflare |
string | — | The name of the cloudflare module's table. The library default is sluis-<instance>-cloudflare. |
backup.config.ports.dynamodb.tables.github |
string | — | The name of the github module's table. The library default is sluis-<instance>-github. |
backup.config.ports.dynamodb.tables.google |
string | — | The name of the google module's table. The library default is sluis-<instance>-google. |
backup.config.ports.dynamodb.tables.oidc |
string | — | The name of the oidc module's table. The library default is sluis-<instance>-oidc. |
backup.config.ports.dynamodb.tables.outline |
string | — | The name of the outline module's table. The library default is sluis-<instance>-outline. |
backup.config.ports.dynamodb.tables.slack |
string | — | The name of the slack module's table. The library default is sluis-<instance>-slack. |
backup.config.preset |
one of server, k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid, k8s-aws, aws-eks | — | The adapters of a whole platform, one per concern: server (no AWS, no Kubernetes), k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid (sluis on Lambda, a cluster for the workloads), k8s-aws (sluis as a pod on Kubernetes with AWS storage: DynamoDB, S3, KMS-wrapped signing; SSM secrets, or OpenBao with adapters.secrets). aws-eks is the deprecated name of k8s-aws. Absent, the preset the platform answers lead to; with neither, the ports keys decide. adapters and the ports keys override single concerns. |
backup.config.secrets |
object | — | How the secrets this document names are delivered (truvity/policy config.md section 5). Absent is env. |
backup.config.secrets.endpoint |
string | — | ssm: overrides the SSM address, for LocalStack. |
backup.config.secrets.grace |
string | "24h" |
ssm: how long the previous value of a rotated client secret is still accepted: the document's previous revision, while the current one is younger than this (docs/decisions/0039-the-issuer-generates-confidential-client-secrets.md, the overlap). |
backup.config.secrets.kmsKeyId |
string | — | ssm: the id, ARN or alias of the customer-managed KMS key the parameters the service itself writes (its credentials) are encrypted with. Unset, the AWS-managed alias/aws/ssm. The ssm secrets adapter's kmsKeyId setting; naming another there is refused. |
backup.config.secrets.layout |
one of v5 | — | ssm, required: the storage layout of the installation's secrets, v5, the only one: the module first, <root>/internal/<module>/ and <root>/external/<module>/ (docs/decisions/0072-storage-layout-v5-module-first.md). Layout v4 was removed in v1.77.1 (an installation still on it migrates with sluis migrate v5 of v1.77.0 first), and with it the reading of an absent layout as v4. |
backup.config.secrets.readCache |
string | "5m" |
ssm: how long a process keeps a document it read; a write drops it. 0s is off. SLUIS_SECRETS_READ_CACHE_TTL overrides. |
backup.config.secrets.refresh |
string | "1m" |
ssm: how old a secret's copy may be before it is read again: a rotated secret reaches every instance within it. |
backup.config.secrets.region |
string | — | ssm: the region. Unset follows the AWS SDK's own resolution. |
backup.config.secrets.root |
string | — | file: the directory the secrets are mounted under. ssm: the installation's root, /sluis/ |
backup.config.secrets.source |
one of env, file, ssm | "env" |
env: the variable SLUIS_SECRET_file: the file ssm: a SecureString in AWS SSM Parameter Store under layout): a name the service knows is read at its module's address (<root>/internal/oidc/state-secret, ...), any other at <root>/internal/config/<name>. |
backup.enabled |
boolean | false |
Render the backup CronJob, its ServiceAccount and the document's ConfigMap. Refused unless config names backup.target and layout v5. |
backup.failedJobsHistoryLimit |
integer | 3 |
|
backup.nodeSelector |
object | — | |
backup.podAnnotations |
object | — | |
backup.prune |
object | — | A second CronJob that applies the retention rule (sluis backup prune). |
backup.prune.enabled |
boolean | true |
Render it with the backup CronJob. |
backup.prune.schedule |
string | "47 3 * * *" |
Cron schedule of the prune. |
backup.resources |
object | — | |
backup.schedule |
string | "17 2 * * *" |
Cron schedule of the backup run. |
backup.secretEnv |
array | — | Environment variables from a Secret's keys: the holders of the secrets the config names (valkey.passwordEnv, oauthClient.secretEnv, adminPasswordEnv). A secret is never in config. |
backup.secretEnv[].key |
string | required | The key in the Secret. |
backup.secretEnv[].name |
string | required | The variable, as the config names it. |
backup.secretEnv[].optional |
boolean | — | Start without it when the Secret or the key is absent. |
backup.secretEnv[].secretName |
string | required | The Secret. |
backup.serviceAccount |
object | — | The backup role's own account: it reads every module and writes the archive, so it is never the service's. Name empty: |
backup.serviceAccount.annotations |
object | — | |
backup.serviceAccount.annotations.<name> |
string | — | |
backup.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
backup.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
backup.serviceAccount.name |
string | — | |
backup.startingDeadlineSeconds |
integer | 3600 |
|
backup.successfulJobsHistoryLimit |
integer | 3 |
|
backup.suspend |
boolean | false |
Suspend the CronJobs without removing them. |
backup.timeZone |
string | — | IANA time zone of the schedule. Empty: the controller manager's. |
backup.tolerations |
array | — | |
config |
object | — | Rendered as it stands, with the apiVersion the chart writes, into a ConfigMap mounted as the directory holding the file the binary reads with --config. Its schema is sluis's: schemas/config/sluis.schema.json. |
console |
object | — | Where the console is mounted on the issuer's origin. The rest of what the console is configured with is the config's. |
console.mount |
string | — | Where the console is mounted on this issuer's origin, e.g. /console. Empty serves no console. |
dashboards |
object | — | Grafana dashboards, rendered with renders: dashboards: a GrafanaFolder and the GrafanaDashboards in it, for the grafana-operator. |
dashboards.clusterFolderUID |
string | — | The uid of this cluster's folder in the shared Grafana. Required in dashboards mode; at most 25 characters. |
dashboards.commonAnnotations |
object | — | Extra annotations merged into the folder and the dashboards. |
dashboards.commonAnnotations.<name> |
string | — | |
dashboards.datasources |
object | — | The uids of the datasources the dashboards offer by default. Required in dashboards mode. |
dashboards.datasources.logs |
string | — | The logs datasource uid. |
dashboards.datasources.metrics |
string | — | The metrics datasource uid. |
dashboards.instanceSelector |
object | — | Which Grafana the objects go to; a full selector. Empty: the shared one (observability.truvity.io/grafana: shared). |
directory |
object | — | The corporate directories this service reads itself. The workspaces a deployment declares are the config's: config.directory.workspaces, each key file mounted with secretMounts. |
directory.push |
object | — | Copy the credential of every connected workspace to a secret store with an External Secrets PushSecret, for recovery: the whole Secret bundled under one remote key, because the key names inside it are not stable. Absent pushes nothing. deletionPolicy is deliberately not settable -- the case this exists for is the Secret going away. |
directory.push.refreshInterval |
string | — | |
directory.push.remoteKey |
string | required | |
directory.push.secretStore |
object | required | |
directory.push.secretStore.kind |
one of SecretStore, ClusterSecretStore | — | |
directory.push.secretStore.name |
string | required | |
documents |
object | — | The rendered documents of one installation (sluisctl render), each as the string the file holds. The chart puts them into their ConfigMaps unchanged and holds them to what it mounts; it does not rewrite them. Set both or neither. With them, config, policy, exchange.clusters and exchange.aws.accounts are not used. |
documents.policy |
string | — | The policy document (policy.yaml, apiVersion sluis.truvity.github.io/policy/v2). |
documents.service |
string | — | The service document (sluis.yaml, apiVersion sluis.truvity.github.io/sluis/v3). |
exchange |
object | — | |
exchange.aws |
object | — | AWS accounts whose IAM roles may exchange their outbound-identity-federation token. Empty verifies none. |
exchange.aws.accounts |
array | — | |
exchange.aws.accounts[].account |
string | required | The 12-digit AWS account id. |
exchange.aws.accounts[].algs |
array | — | |
exchange.aws.accounts[].issuer |
string | required | The account's token issuer, from get-outbound-web-identity-federation-info. |
exchange.aws.accounts[].jwksUri |
string | — | Where its public keys are. Empty means |
exchange.aws.accounts[].name |
string | required | The estate's word for the account, for logs. |
exchange.aws.accounts[].orgId |
string | — | Require this AWS Organizations id in the token. |
exchange.aws.audience |
string | — | The audience the role must request from STS. Empty means the issuer's own URL. |
exchange.aws.maxAge |
string | — | Refuse a token whose iat is older, whatever its exp allows. Default 5m, at most 1h. |
exchange.clusters |
array | — | Clusters whose workloads may exchange, each verified against the key set that cluster publishes. No secret in any row. |
exchange.clusters[].issuer |
string | required | The iss its ServiceAccount tokens carry. |
exchange.clusters[].jwksUri |
string | — | Where its public keys are. Empty discovers it from the issuer. |
exchange.clusters[].name |
string | required | The estate's word for the cluster; what a workload matcher names. |
fullnameOverride |
string | — | Replaces the release's full name, the prefix of every object the chart renders and the value config.release must carry. An installation migrating from the access-issuer chart sets it to the old full name so no object is renamed. |
githubApps |
object | — | |
githubApps.catalogue |
array | — | GitHub Apps declared as data, created and installed from the console. The service validates the whole catalogue again at start. |
githubApps.catalogue[].description |
string | — | |
githubApps.catalogue[].events |
array | — | |
githubApps.catalogue[].grants |
array | — | |
githubApps.catalogue[].grants[].group |
string | required | |
githubApps.catalogue[].grants[].permissions |
object | required | |
githubApps.catalogue[].grants[].permissions.<name> |
one of read, write, admin | — | |
githubApps.catalogue[].grants[].repositories |
array | required | |
githubApps.catalogue[].id |
string | required | |
githubApps.catalogue[].installation |
one of all, selected | — | |
githubApps.catalogue[].name |
string | — | |
githubApps.catalogue[].org |
string | required | |
githubApps.catalogue[].permissions |
object | required | |
githubApps.catalogue[].permissions.<name> |
one of read, write, admin | — | |
githubApps.catalogue[].public |
boolean | — | |
githubApps.catalogue[].push |
object | — | Copy this App's credential to a secret store with an External Secrets PushSecret: its three property keys only, to the store and path named here. Absent pushes nothing. |
githubApps.catalogue[].push.deletionPolicy |
one of None, Delete | — | |
githubApps.catalogue[].push.refreshInterval |
string | — | |
githubApps.catalogue[].push.remoteKey |
string | required | |
githubApps.catalogue[].push.secretStore |
object | required | |
githubApps.catalogue[].push.secretStore.kind |
one of SecretStore, ClusterSecretStore | — | |
githubApps.catalogue[].push.secretStore.name |
string | required | |
githubApps.push |
object | — | Copy the link App and one App per bound organisation to a secret store with an External Secrets PushSecret, for recovery: the whole Secret bundled under one remote key, because the key names inside it are not stable. Absent pushes nothing. deletionPolicy is deliberately not settable -- the case this exists for is the Secret going away. |
githubApps.push.refreshInterval |
string | — | |
githubApps.push.remoteKey |
string | required | |
githubApps.push.secretStore |
object | required | |
githubApps.push.secretStore.kind |
one of SecretStore, ClusterSecretStore | — | |
githubApps.push.secretStore.name |
string | required | |
image |
object | — | |
image.perModule |
boolean | — | Run each module from its own image (sluis-issuer, sluis-backup) beside image.repository, at the same tag, instead of the one multi-call image. |
image.pullPolicy |
one of Always, IfNotPresent, Never | — | |
image.repository |
string | — | |
image.tag |
string | — | |
modules |
object | — | The per-module workloads (decision D-v176-9): the chart renders no single Deployment. The issuer is always rendered, another module when it is enabled. |
modules.cloudflare |
object | — | The Cloudflare module (the STS minter's rotation), with a Service on /rpc. |
modules.cloudflare.audience |
string | — | The audience a call to this module carries: the module's name when empty. |
modules.cloudflare.config |
object | — | The module's document, without its apiVersion. Required once the module is enabled. |
modules.cloudflare.enabled |
boolean | false |
Render this module's Deployment, ServiceAccount and ConfigMap (and, for a module that answers calls, its Service). |
modules.cloudflare.image |
object | — | Overrides the chart's image for this module. Unset takes image (and image.perModule). |
modules.cloudflare.image.repository |
string | — | |
modules.cloudflare.image.tag |
string | — | |
modules.cloudflare.podDisruptionBudget |
object | — | The module's PodDisruptionBudget: maxUnavailable 1 unless minAvailable is given (one of the two; a number at or above the replicas is refused). |
modules.cloudflare.podDisruptionBudget.enabled |
boolean | true |
|
modules.cloudflare.podDisruptionBudget.maxUnavailable |
integer or string | 1 |
A number of pods, or a percentage such as 50%. |
modules.cloudflare.podDisruptionBudget.minAvailable |
integer or string | — | A number of pods, or a percentage such as 50%. |
modules.cloudflare.replicas |
integer or null | — | Replicas. Unset: replicaCount for the issuer, 1 for another module. More than one controller replica needs the tick leases in a State they share. |
modules.cloudflare.resources |
object | — | |
modules.cloudflare.rpcPort |
integer | 8081 |
The port of the module's Service on /rpc, and of its listener. |
modules.cloudflare.serviceAccount |
object | — | This module's own account. Name empty: serviceAccount.name when that is set). With irsa, each module but the issuer has its own awsRoleArn; the issuer takes the release's. |
modules.cloudflare.serviceAccount.annotations |
object | — | |
modules.cloudflare.serviceAccount.annotations.<name> |
string | — | |
modules.cloudflare.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
modules.cloudflare.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
modules.cloudflare.serviceAccount.name |
string | — | |
modules.github |
object | — | The GitHub module (the controller), with a Service on /rpc. |
modules.github.audience |
string | — | The audience a call to this module carries: the module's name when empty. |
modules.github.config |
object | — | The GitHub module's document, without its apiVersion, over config.controllers.github. Its schema is schemas/config/controller-github.schema.json. |
modules.github.config.adapters |
object | — | Names the adapter of single concerns, over the preset and the ports keys. The names and what each needs are in the matrix of docs/reference/sluis/adapters.md. |
modules.github.config.adapters.audit |
object | — | The adapter for the audit sink, replacing the preset's. |
modules.github.config.adapters.audit.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.audit.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.adapters.blobs |
object | — | The adapter for blobs, replacing the preset's. |
modules.github.config.adapters.blobs.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.blobs.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.adapters.schedule |
object | — | The adapter for the schedule of passes, replacing the preset's. |
modules.github.config.adapters.schedule.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.schedule.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.adapters.secrets |
object | — | The adapter for secrets (dynamic secrets), replacing the preset's. |
modules.github.config.adapters.secrets.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.secrets.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.adapters.signing |
object | — | The adapter for token signing, replacing the preset's. |
modules.github.config.adapters.signing.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.signing.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.adapters.state |
object | — | The adapter for state, sessions included, replacing the preset's. |
modules.github.config.adapters.state.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.state.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.adapters.trigger |
object | — | The adapter for the "run a pass now" trigger, replacing the preset's. |
modules.github.config.adapters.trigger.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.github.config.adapters.trigger.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.github.config.appsDir |
string | "/var/run/github-roster/apps" |
One file per connected organisation: its App's credentials. |
modules.github.config.audit |
object | — | The audit installation the controller records to, as its own workload. Unset only logs what it did. |
modules.github.config.audit.tokenFile |
string | — | This workload's projected service-account token. |
modules.github.config.audit.writer |
string | — | The installation's receiver. |
modules.github.config.console |
object | — | How the controller proves itself to the console, when the pod's tokenFile is not the way. |
modules.github.config.console.auth |
object | — | The proof. Absent, tokenFile. |
modules.github.config.console.auth.aws |
object | — | The function role's AWS outbound web identity token (sts:GetWebIdentityToken), re-minted every four minutes. The console's issuer must federate the account, and its policy must declare an aws matcher for the role. |
modules.github.config.console.auth.aws.audience |
string | required | The audience requested from STS. It must equal the issuer's console.awsAudience (default <issuerURL>/console), NOT the audience of its AWS federation file. |
modules.github.config.consoleURL |
string | — | The console's API, which answers who holds a group. |
modules.github.config.github |
object | — | The GitHub module's routing (docs/decisions/0071). Unset keeps the module in this process. |
modules.github.config.github.remote |
object | — | Where the GitHub module is when it is not this process: the calls to it go there. Set exactly one of function and url. Unset keeps the module in this process. |
modules.github.config.github.remote.audience |
string | — | The audience of that token. The module's name, github, when unset. |
modules.github.config.github.remote.function |
string | — | The module's Lambda function, name or ARN. It is invoked through the live-<class> alias of this process's caller class. |
modules.github.config.github.remote.tokenFile |
string | — | Where the projected token is mounted. /var/run/secrets/sluis/github/token when unset. |
modules.github.config.github.remote.url |
string | — | The module's Kubernetes Service. A call carries the pod's projected ServiceAccount token. |
modules.github.config.github.serve |
object | — | Makes the GitHub module answer the issuer's calls on Kubernetes (docs/decisions/0071). Only the module's own document sets it. The module listens on address and accepts a call whose projected ServiceAccount token was minted for audience, checked with a TokenReview, and whose subject is one of issuers; any other call is a 401. On Lambda the function answers rpc events and IAM decides who may invoke it. Not with remote. Unset serves nothing. |
modules.github.config.github.serve.address |
string | — | The listener, host:port; it also answers GET /healthz. :8081 when unset. |
modules.github.config.github.serve.audience |
string | — | The audience a caller's token must be minted for. The module's name, github, when unset. |
modules.github.config.github.serve.issuers |
array | required | The issuer's ServiceAccount, as system:serviceaccount:<namespace>:<name>. A call from it is both the issuer class (mint_installation) and the console class (the console methods); a token of any other subject is a 401. |
modules.github.config.google |
object | — | The Google module's routing (docs/decisions/0071). Unset keeps the module in this process. |
modules.github.config.google.remote |
object | — | Where the Google module is when it is not this process: the calls to it go there. Set exactly one of function and url. Unset keeps the module in this process. |
modules.github.config.google.remote.audience |
string | — | The audience of that token. The module's name, google, when unset. |
modules.github.config.google.remote.function |
string | — | The module's Lambda function, name or ARN. It is invoked through the live-<class> alias of this process's caller class. |
modules.github.config.google.remote.tokenFile |
string | — | Where the projected token is mounted. /var/run/secrets/sluis/google/token when unset. |
modules.github.config.google.remote.url |
string | — | The module's Kubernetes Service. A call carries the pod's projected ServiceAccount token. |
modules.github.config.interval |
string | "15m" |
How long between passes. Positive. |
modules.github.config.log |
object | — | Structured logging. One level for the whole service: per-package levels are deliberately not part of the contract. |
modules.github.config.log.level |
one of debug, info, warn, error | "info" |
The lowest level that is written. |
modules.github.config.platform |
object | — | What this installation has to build on. The answers pick a preset (the decision tree in docs/concepts/sluis/ports.md), and start refuses an adapter that needs an answer that is no. Absent, the ports keys decide and nothing is checked against the platform. |
modules.github.config.platform.aws |
boolean | — | AWS is available: its credentials, DynamoDB, S3, SSM, KMS, SQS and EventBridge. |
modules.github.config.platform.kubernetes |
boolean | — | A Kubernetes cluster is available. |
modules.github.config.platform.openbao |
boolean | — | An OpenBao is available. |
modules.github.config.platform.replicas |
integer | 1 |
How many replicas share this installation's state. Above 1 start refuses an adapter that keeps its data in the process (memory). |
modules.github.config.platform.runtime |
one of kubernetes, lambda, process | — | Where sluis itself runs. Absent: kubernetes with a cluster, else lambda on AWS, else process. |
modules.github.config.policy |
object | — | The policy document: the bindings are its github table, and its controllers.github section is what this controller may change. |
modules.github.config.policy.file |
string | required | The policy document: the one canonical file sluisctl policy render writes (schemas/config/policy.schema.json). Read once, at start: a change is a new instance. |
modules.github.config.ports |
object | — | The adapters behind the storage ports (docs/concepts/sluis/ports.md). |
modules.github.config.ports.adapter |
one of legacy, memory, dynamodb | "legacy" |
legacy, the default, is deprecated since v1.74.0 and still ships: migrate with sluis migrate. It keeps state where it has always been kept: the namespace's ConfigMaps and Secrets and, when valkey is set, Valkey. memory keeps all of it in this process, which a restart loses: for a local run and the demonstration, and not with store: kubernetes or valkey. dynamodb keeps the same in one DynamoDB table (ports.dynamodb), with the platform's credentials, and takes its Blob from legacy unless ports.blob names its own. |
modules.github.config.ports.blob |
object | — | Replaces the Blob port (status reports, directory snapshots) with an adapter of its own, whatever ports.adapter is. Absent, the Blob is ports.adapter's. |
modules.github.config.ports.blob.adapter |
one of s3 | required | s3 keeps the blobs in an S3 bucket. |
modules.github.config.ports.blob.s3 |
object | — | Where the S3 adapter keeps its objects. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here. |
modules.github.config.ports.blob.s3.bucket |
string | required | The bucket. It must exist, with public access blocked. |
modules.github.config.ports.blob.s3.checksum |
one of sha256, md5, none | "sha256" |
The integrity header of every upload: sha256 (x-amz-checksum-sha256, computed over the whole body and sent precomputed, never as an aws-chunked trailer), md5 (Content-MD5) or none, for a store that refuses SHA-256. AWS refuses a PutObject without one on an Object Lock bucket. |
modules.github.config.ports.blob.s3.credentials |
object | — | Instead of a static document, sluis mints its own R2 credentials from a Cloudflare preset: the account's minter credential clones the preset's prototype, the credentials are renewed with a third of their lifetime left and minted again once after a 403. Exclusive with credentialsRef. Needs endpoint, the ssm secrets source, and the cloudflare section. |
modules.github.config.ports.blob.s3.credentials.preset |
string | required | A key of cloudflare.presets that has an endpoint (an R2 preset). |
modules.github.config.ports.blob.s3.credentialsRef |
string | — | Where the credentials for endpoint are, in the installation's secrets store (the ssm secrets source): the internal address, internal/<module>/<name>, of the s3-credentials/v1 document (access_key_id, secret_access_key) that holds static credentials, or external/cloudflare/<preset>, the cloudflare/v1 document the Cloudflare module rotates for an R2 preset with store: external (the access key is the token's id; it is read again with a third of its time left and after a 403). Read at start and again after an answer of 403, at most once a minute. Needs endpoint; region defaults to auto with it. Any other address is refused. This is the simple way and needs no cloudflare section in this document, so it is the one to use when the presets are another module's (cloudflare.remote). |
modules.github.config.ports.blob.s3.endpoint |
string | — | Overrides the S3 address: LocalStack or an S3-compatible store (Cloudflare R2, MinIO). |
modules.github.config.ports.blob.s3.kmsKey |
string | — | A KMS key id, ARN or alias for server-side encryption (SSE-KMS) of every write. Absent, the bucket's default encryption applies. |
modules.github.config.ports.blob.s3.pathStyle |
boolean | — | Addresses the bucket in the path and not the host name, which LocalStack and most S3-compatible stores need. |
modules.github.config.ports.blob.s3.prefix |
string | — | A key prefix inside the bucket, for an installation that shares it. |
modules.github.config.ports.blob.s3.region |
string | — | The bucket's region. Absent, the SDK's own resolution (AWS_REGION). |
modules.github.config.ports.dynamodb |
object | — | The DynamoDB tables of the dynamodb adapter: one table per module (tables, layout v5). Each has a string partition key pk, a string sort key sk and the TTL attribute expires. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here; an S3-compatible endpoint with no such identity names a credentials document by address (credentialsRef), never by value. |
modules.github.config.ports.dynamodb.create |
boolean | false |
Create the table (on-demand, TTL on expires) at start when it is not there, for a test or a development installation. Off, the table must exist: production uses the one the infrastructure code made, and the role needs dynamodb:DescribeTable on it (layout v5: the readiness probe asks, not the start). |
modules.github.config.ports.dynamodb.endpoint |
string | — | Overrides the DynamoDB address: LocalStack or DynamoDB Local. |
modules.github.config.ports.dynamodb.region |
string | — | The table's region. Absent, the SDK's own resolution (AWS_REGION). |
modules.github.config.ports.dynamodb.tables |
object | required | Layout v5 (docs/decisions/0072-storage-layout-v5-module-first.md): the table of each module, by module name. A process names its own module's table and the tables of the peers it reads; a module it does not name is not opened. The single table of layout v4 (table) was removed in v1.77.1. |
modules.github.config.ports.dynamodb.tables.backup |
string | — | The name of the backup module's table. The library default is sluis-<instance>-backup. |
modules.github.config.ports.dynamodb.tables.cloudflare |
string | — | The name of the cloudflare module's table. The library default is sluis-<instance>-cloudflare. |
modules.github.config.ports.dynamodb.tables.github |
string | — | The name of the github module's table. The library default is sluis-<instance>-github. |
modules.github.config.ports.dynamodb.tables.google |
string | — | The name of the google module's table. The library default is sluis-<instance>-google. |
modules.github.config.ports.dynamodb.tables.oidc |
string | — | The name of the oidc module's table. The library default is sluis-<instance>-oidc. |
modules.github.config.ports.dynamodb.tables.outline |
string | — | The name of the outline module's table. The library default is sluis-<instance>-outline. |
modules.github.config.ports.dynamodb.tables.slack |
string | — | The name of the slack module's table. The library default is sluis-<instance>-slack. |
modules.github.config.preset |
one of server, k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid, k8s-aws, aws-eks | — | The adapters of a whole platform, one per concern: server (no AWS, no Kubernetes), k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid (sluis on Lambda, a cluster for the workloads), k8s-aws (sluis as a pod on Kubernetes with AWS storage: DynamoDB, S3, KMS-wrapped signing; SSM secrets, or OpenBao with adapters.secrets). aws-eks is the deprecated name of k8s-aws. Absent, the preset the platform answers lead to; with neither, the ports keys decide. adapters and the ports keys override single concerns. |
modules.github.config.probes |
object | {"address":":7070"} |
The health listener. Separate from the service's own traffic, so that readiness is answerable when the service's listener is saturated, and so that a probe is not reachable from outside. |
modules.github.config.probes.address |
string | required | host:port for /health/live and /health/ready. |
modules.github.config.recordsDir |
string | "/var/run/github-roster/records" |
The console's records, mounted. |
modules.github.config.release |
string | "sluis" |
The name the installation's objects carry. It must be the release's full name: the controller reads the report and the records the service writes under it. |
modules.github.config.secrets |
object | — | How the secrets this document names are delivered (truvity/policy config.md section 5). Absent is env. |
modules.github.config.secrets.endpoint |
string | — | ssm: overrides the SSM address, for LocalStack. |
modules.github.config.secrets.grace |
string | "24h" |
ssm: how long the previous value of a rotated client secret is still accepted: the document's previous revision, while the current one is younger than this (docs/decisions/0039-the-issuer-generates-confidential-client-secrets.md, the overlap). |
modules.github.config.secrets.kmsKeyId |
string | — | ssm: the id, ARN or alias of the customer-managed KMS key the parameters the service itself writes (its credentials) are encrypted with. Unset, the AWS-managed alias/aws/ssm. The ssm secrets adapter's kmsKeyId setting; naming another there is refused. |
modules.github.config.secrets.layout |
one of v5 | — | ssm, required: the storage layout of the installation's secrets, v5, the only one: the module first, <root>/internal/<module>/ and <root>/external/<module>/ (docs/decisions/0072-storage-layout-v5-module-first.md). Layout v4 was removed in v1.77.1 (an installation still on it migrates with sluis migrate v5 of v1.77.0 first), and with it the reading of an absent layout as v4. |
modules.github.config.secrets.readCache |
string | "5m" |
ssm: how long a process keeps a document it read; a write drops it. 0s is off. SLUIS_SECRETS_READ_CACHE_TTL overrides. |
modules.github.config.secrets.refresh |
string | "1m" |
ssm: how old a secret's copy may be before it is read again: a rotated secret reaches every instance within it. |
modules.github.config.secrets.region |
string | — | ssm: the region. Unset follows the AWS SDK's own resolution. |
modules.github.config.secrets.root |
string | — | file: the directory the secrets are mounted under. ssm: the installation's root, /sluis/ |
modules.github.config.secrets.source |
one of env, file, ssm | "env" |
env: the variable SLUIS_SECRET_file: the file ssm: a SecureString in AWS SSM Parameter Store under layout): a name the service knows is read at its module's address (<root>/internal/oidc/state-secret, ...), any other at <root>/internal/config/<name>. |
modules.github.config.slack |
object | — | The Slack module's routing (docs/decisions/0071). Unset keeps the module in this process. |
modules.github.config.slack.remote |
object | — | Where the Slack module is when it is not this process: the calls to it go there. Set exactly one of function and url. Unset keeps the module in this process. |
modules.github.config.slack.remote.audience |
string | — | The audience of that token. The module's name, slack, when unset. |
modules.github.config.slack.remote.function |
string | — | The module's Lambda function, name or ARN. It is invoked through the live-<class> alias of this process's caller class. |
modules.github.config.slack.remote.tokenFile |
string | — | Where the projected token is mounted. /var/run/secrets/sluis/slack/token when unset. |
modules.github.config.slack.remote.url |
string | — | The module's Kubernetes Service. A call carries the pod's projected ServiceAccount token. |
modules.github.config.slack.serve |
object | — | Makes the Slack module answer the issuer's calls on Kubernetes (docs/decisions/0071). Only the module's own document sets it. The module listens on address and accepts a call whose projected ServiceAccount token was minted for audience, checked with a TokenReview, and whose subject is one of issuers; any other call is a 401. On Lambda the function answers rpc events and IAM decides who may invoke it. Not with remote. Unset serves nothing. |
modules.github.config.slack.serve.address |
string | — | The listener, host:port; it also answers GET /healthz. :8081 when unset. |
modules.github.config.slack.serve.audience |
string | — | The audience a caller's token must be minted for. The module's name, slack, when unset. |
modules.github.config.slack.serve.issuers |
array | required | The issuer's ServiceAccount, as system:serviceaccount:<namespace>:<name>. A call from it is both the issuer class (mint_installation) and the console class (the console methods); a token of any other subject is a 401. |
modules.github.config.tokenFile |
string | "/var/run/secrets/github-roster/token" |
This pod's projected ServiceAccount token, presented to the console and read afresh on every call. |
modules.github.enabled |
boolean | false |
Render this module's Deployment, ServiceAccount and ConfigMap (and, for a module that answers calls, its Service). |
modules.github.image |
object | — | Overrides the chart's image for this module. Unset takes image (and image.perModule). |
modules.github.image.repository |
string | — | |
modules.github.image.tag |
string | — | |
modules.github.podDisruptionBudget |
object | — | The module's PodDisruptionBudget: maxUnavailable 1 unless minAvailable is given (one of the two; a number at or above the replicas is refused). |
modules.github.podDisruptionBudget.enabled |
boolean | true |
|
modules.github.podDisruptionBudget.maxUnavailable |
integer or string | 1 |
A number of pods, or a percentage such as 50%. |
modules.github.podDisruptionBudget.minAvailable |
integer or string | — | A number of pods, or a percentage such as 50%. |
modules.github.replicas |
integer or null | — | Replicas. Unset: replicaCount for the issuer, 1 for another module. More than one controller replica needs the tick leases in a State they share. |
modules.github.resources |
object | — | |
modules.github.rpcPort |
integer | 8081 |
The port of the module's Service on /rpc, and of its listener. |
modules.github.serviceAccount |
object | — | This module's own account. Name empty: serviceAccount.name when that is set). With irsa, each module but the issuer has its own awsRoleArn; the issuer takes the release's. |
modules.github.serviceAccount.annotations |
object | — | |
modules.github.serviceAccount.annotations.<name> |
string | — | |
modules.github.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
modules.github.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
modules.github.serviceAccount.name |
string | — | |
modules.google |
object | — | The Google directory module, with a Service on /rpc. |
modules.google.audience |
string | — | The audience a call to this module carries: the module's name when empty. |
modules.google.config |
object | — | The module's document, without its apiVersion. Required once the module is enabled. |
modules.google.enabled |
boolean | false |
Render this module's Deployment, ServiceAccount and ConfigMap (and, for a module that answers calls, its Service). |
modules.google.image |
object | — | Overrides the chart's image for this module. Unset takes image (and image.perModule). |
modules.google.image.repository |
string | — | |
modules.google.image.tag |
string | — | |
modules.google.podDisruptionBudget |
object | — | The module's PodDisruptionBudget: maxUnavailable 1 unless minAvailable is given (one of the two; a number at or above the replicas is refused). |
modules.google.podDisruptionBudget.enabled |
boolean | true |
|
modules.google.podDisruptionBudget.maxUnavailable |
integer or string | 1 |
A number of pods, or a percentage such as 50%. |
modules.google.podDisruptionBudget.minAvailable |
integer or string | — | A number of pods, or a percentage such as 50%. |
modules.google.replicas |
integer or null | — | Replicas. Unset: replicaCount for the issuer, 1 for another module. More than one controller replica needs the tick leases in a State they share. |
modules.google.resources |
object | — | |
modules.google.rpcPort |
integer | 8081 |
The port of the module's Service on /rpc, and of its listener. |
modules.google.serviceAccount |
object | — | This module's own account. Name empty: serviceAccount.name when that is set). With irsa, each module but the issuer has its own awsRoleArn; the issuer takes the release's. |
modules.google.serviceAccount.annotations |
object | — | |
modules.google.serviceAccount.annotations.<name> |
string | — | |
modules.google.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
modules.google.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
modules.google.serviceAccount.name |
string | — | |
modules.issuer |
object | — | The issuer: OIDC, the signer and the console. Always rendered. Its document is config without controllers, plus a <module>.remote ({url, audience, tokenFile}) for each enabled module that answers calls. It owns the release's Service and the routes. |
modules.issuer.autoscaling |
object | — | A HorizontalPodAutoscaler (autoscaling/v2) for the issuer, the one module that scales: a controller runs one pass at a time under a lease. It owns the replica count, so replicas stays unset. A utilisation target is a share of resources.requests, which it requires. |
modules.issuer.autoscaling.enabled |
boolean | false |
|
modules.issuer.autoscaling.maxReplicas |
integer | 4 |
|
modules.issuer.autoscaling.minReplicas |
integer | 2 |
|
modules.issuer.autoscaling.targetCPUUtilizationPercentage |
integer or null | 80 |
|
modules.issuer.autoscaling.targetMemoryUtilizationPercentage |
integer or null | — | |
modules.issuer.image |
object | — | Overrides the chart's image for this module. Unset takes image (and image.perModule). |
modules.issuer.image.repository |
string | — | |
modules.issuer.image.tag |
string | — | |
modules.issuer.podDisruptionBudget |
object | — | The module's PodDisruptionBudget: maxUnavailable 1 unless minAvailable is given (one of the two; a number at or above the replicas is refused). |
modules.issuer.podDisruptionBudget.enabled |
boolean | true |
|
modules.issuer.podDisruptionBudget.maxUnavailable |
integer or string | 1 |
A number of pods, or a percentage such as 50%. |
modules.issuer.podDisruptionBudget.minAvailable |
integer or string | — | A number of pods, or a percentage such as 50%. |
modules.issuer.replicas |
integer or null | — | Replicas. Unset: replicaCount for the issuer, 1 for another module. More than one controller replica needs the tick leases in a State they share. |
modules.issuer.resources |
object | — | |
modules.issuer.serviceAccount |
object | — | This module's own account. Name empty: serviceAccount.name when that is set). With irsa, each module but the issuer has its own awsRoleArn; the issuer takes the release's. |
modules.issuer.serviceAccount.annotations |
object | — | |
modules.issuer.serviceAccount.annotations.<name> |
string | — | |
modules.issuer.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
modules.issuer.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
modules.issuer.serviceAccount.name |
string | — | |
modules.outline |
object | — | The Outline module (the controller, docs/decisions/0077), with a Service on /rpc for the issuer's console calls. The issuer never runs it: its document then holds only outline.remote, which the chart writes. |
modules.outline.audience |
string | — | The audience a call to this module carries: the module's name when empty. |
modules.outline.config |
object | — | The Outline module's document, without its apiVersion, which the chart writes (sluis-outline/v1). Required once the module is enabled; there is no config.controllers.outline. The chart fills consoleURL, policy.file and outline.serve when they are unset. Its schema is schemas/config/sluis-outline.schema.json. |
modules.outline.config.adapters |
object | — | Names the adapter of single concerns, over the preset and the ports keys. The names and what each needs are in the matrix of docs/reference/sluis/adapters.md. |
modules.outline.config.adapters.audit |
object | — | The adapter for the audit sink, replacing the preset's. |
modules.outline.config.adapters.audit.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.audit.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.adapters.blobs |
object | — | The adapter for blobs, replacing the preset's. |
modules.outline.config.adapters.blobs.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.blobs.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.adapters.schedule |
object | — | The adapter for the schedule of passes, replacing the preset's. |
modules.outline.config.adapters.schedule.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.schedule.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.adapters.secrets |
object | — | The adapter for secrets (dynamic secrets), replacing the preset's. |
modules.outline.config.adapters.secrets.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.secrets.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.adapters.signing |
object | — | The adapter for token signing, replacing the preset's. |
modules.outline.config.adapters.signing.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.signing.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.adapters.state |
object | — | The adapter for state, sessions included, replacing the preset's. |
modules.outline.config.adapters.state.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.state.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.adapters.trigger |
object | — | The adapter for the "run a pass now" trigger, replacing the preset's. |
modules.outline.config.adapters.trigger.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.outline.config.adapters.trigger.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.outline.config.audit |
object | — | The audit installation the controller records to, as its own workload. Unset only logs what it did. |
modules.outline.config.audit.tokenFile |
string | — | This workload's projected service-account token. |
modules.outline.config.audit.writer |
string | — | The installation's receiver. |
modules.outline.config.console |
object | — | How the controller proves itself to the console, when the pod's tokenFile is not the way. |
modules.outline.config.console.auth |
object | — | The proof. Absent, tokenFile. |
modules.outline.config.console.auth.aws |
object | — | The function role's AWS outbound web identity token (sts:GetWebIdentityToken), re-minted every four minutes. The console's issuer must federate the account, and its policy must declare an aws matcher for the role. |
modules.outline.config.console.auth.aws.audience |
string | required | The audience requested from STS. It must equal the issuer's console.awsAudience (default <issuerURL>/console), NOT the audience of its AWS federation file. |
modules.outline.config.consoleURL |
string | — | The console's API, which answers who holds a group. |
modules.outline.config.interval |
string | "2m" |
How long between passes. Positive. Short, because a person signing in for the first time sees nothing but their own documents until the next pass. |
modules.outline.config.log |
object | — | Structured logging. One level for the whole service: per-package levels are deliberately not part of the contract. |
modules.outline.config.log.level |
one of debug, info, warn, error | "info" |
The lowest level that is written. |
modules.outline.config.outline |
object | — | What is the Outline module's own (docs/reference/sluis/outline.md). |
modules.outline.config.outline.serve |
object | — | Makes the Outline module answer the console's calls on Kubernetes. The module listens on address and accepts a call whose projected ServiceAccount token was minted for audience, checked with a TokenReview, and whose subject is one of issuers; any other call is a 401. On Lambda the function answers rpc events and IAM decides who may invoke it. Unset serves nothing. |
modules.outline.config.outline.serve.address |
string | — | The listener, host:port; it also answers GET /healthz. :8081 when unset. |
modules.outline.config.outline.serve.audience |
string | — | The audience a caller's token must be minted for. The module's name, outline, when unset. |
modules.outline.config.outline.serve.issuers |
array | required | The issuer's ServiceAccount, as system:serviceaccount:<namespace>:<name>. A call from it is both the issuer class (mint_installation) and the console class (the console methods); a token of any other subject is a 401. |
modules.outline.config.outline.shareScan |
string | "1h" |
How often the single-document shares in the collections that name a directory are read and reported. Each document is two calls to Outline. |
modules.outline.config.platform |
object | — | What this installation has to build on. The answers pick a preset (the decision tree in docs/concepts/sluis/ports.md), and start refuses an adapter that needs an answer that is no. Absent, the ports keys decide and nothing is checked against the platform. |
modules.outline.config.platform.aws |
boolean | — | AWS is available: its credentials, DynamoDB, S3, SSM, KMS, SQS and EventBridge. |
modules.outline.config.platform.kubernetes |
boolean | — | A Kubernetes cluster is available. |
modules.outline.config.platform.openbao |
boolean | — | An OpenBao is available. |
modules.outline.config.platform.replicas |
integer | 1 |
How many replicas share this installation's state. Above 1 start refuses an adapter that keeps its data in the process (memory). |
modules.outline.config.platform.runtime |
one of kubernetes, lambda, process | — | Where sluis itself runs. Absent: kubernetes with a cluster, else lambda on AWS, else process. |
modules.outline.config.policy |
object | — | The policy document: the bindings are its outline table, and its controllers.outline.enabledWorkspaces is what this module may change. |
modules.outline.config.policy.file |
string | required | The policy document: the one canonical file sluisctl policy render writes (schemas/config/policy.schema.json). Read once, at start: a change is a new instance. |
modules.outline.config.ports |
object | — | The adapters behind the storage ports (docs/concepts/sluis/ports.md). |
modules.outline.config.ports.adapter |
one of legacy, memory, dynamodb | "legacy" |
legacy, the default, is deprecated since v1.74.0 and still ships: migrate with sluis migrate. It keeps state where it has always been kept: the namespace's ConfigMaps and Secrets and, when valkey is set, Valkey. memory keeps all of it in this process, which a restart loses: for a local run and the demonstration, and not with store: kubernetes or valkey. dynamodb keeps the same in one DynamoDB table (ports.dynamodb), with the platform's credentials, and takes its Blob from legacy unless ports.blob names its own. |
modules.outline.config.ports.blob |
object | — | Replaces the Blob port (status reports, directory snapshots) with an adapter of its own, whatever ports.adapter is. Absent, the Blob is ports.adapter's. |
modules.outline.config.ports.blob.adapter |
one of s3 | required | s3 keeps the blobs in an S3 bucket. |
modules.outline.config.ports.blob.s3 |
object | — | Where the S3 adapter keeps its objects. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here. |
modules.outline.config.ports.blob.s3.bucket |
string | required | The bucket. It must exist, with public access blocked. |
modules.outline.config.ports.blob.s3.checksum |
one of sha256, md5, none | "sha256" |
The integrity header of every upload: sha256 (x-amz-checksum-sha256, computed over the whole body and sent precomputed, never as an aws-chunked trailer), md5 (Content-MD5) or none, for a store that refuses SHA-256. AWS refuses a PutObject without one on an Object Lock bucket. |
modules.outline.config.ports.blob.s3.credentials |
object | — | Instead of a static document, sluis mints its own R2 credentials from a Cloudflare preset: the account's minter credential clones the preset's prototype, the credentials are renewed with a third of their lifetime left and minted again once after a 403. Exclusive with credentialsRef. Needs endpoint, the ssm secrets source, and the cloudflare section. |
modules.outline.config.ports.blob.s3.credentials.preset |
string | required | A key of cloudflare.presets that has an endpoint (an R2 preset). |
modules.outline.config.ports.blob.s3.credentialsRef |
string | — | Where the credentials for endpoint are, in the installation's secrets store (the ssm secrets source): the internal address, internal/<module>/<name>, of the s3-credentials/v1 document (access_key_id, secret_access_key) that holds static credentials, or external/cloudflare/<preset>, the cloudflare/v1 document the Cloudflare module rotates for an R2 preset with store: external (the access key is the token's id; it is read again with a third of its time left and after a 403). Read at start and again after an answer of 403, at most once a minute. Needs endpoint; region defaults to auto with it. Any other address is refused. This is the simple way and needs no cloudflare section in this document, so it is the one to use when the presets are another module's (cloudflare.remote). |
modules.outline.config.ports.blob.s3.endpoint |
string | — | Overrides the S3 address: LocalStack or an S3-compatible store (Cloudflare R2, MinIO). |
modules.outline.config.ports.blob.s3.kmsKey |
string | — | A KMS key id, ARN or alias for server-side encryption (SSE-KMS) of every write. Absent, the bucket's default encryption applies. |
modules.outline.config.ports.blob.s3.pathStyle |
boolean | — | Addresses the bucket in the path and not the host name, which LocalStack and most S3-compatible stores need. |
modules.outline.config.ports.blob.s3.prefix |
string | — | A key prefix inside the bucket, for an installation that shares it. |
modules.outline.config.ports.blob.s3.region |
string | — | The bucket's region. Absent, the SDK's own resolution (AWS_REGION). |
modules.outline.config.ports.dynamodb |
object | — | The DynamoDB tables of the dynamodb adapter: one table per module (tables, layout v5). Each has a string partition key pk, a string sort key sk and the TTL attribute expires. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here; an S3-compatible endpoint with no such identity names a credentials document by address (credentialsRef), never by value. |
modules.outline.config.ports.dynamodb.create |
boolean | false |
Create the table (on-demand, TTL on expires) at start when it is not there, for a test or a development installation. Off, the table must exist: production uses the one the infrastructure code made, and the role needs dynamodb:DescribeTable on it (layout v5: the readiness probe asks, not the start). |
modules.outline.config.ports.dynamodb.endpoint |
string | — | Overrides the DynamoDB address: LocalStack or DynamoDB Local. |
modules.outline.config.ports.dynamodb.region |
string | — | The table's region. Absent, the SDK's own resolution (AWS_REGION). |
modules.outline.config.ports.dynamodb.tables |
object | required | Layout v5 (docs/decisions/0072-storage-layout-v5-module-first.md): the table of each module, by module name. A process names its own module's table and the tables of the peers it reads; a module it does not name is not opened. The single table of layout v4 (table) was removed in v1.77.1. |
modules.outline.config.ports.dynamodb.tables.backup |
string | — | The name of the backup module's table. The library default is sluis-<instance>-backup. |
modules.outline.config.ports.dynamodb.tables.cloudflare |
string | — | The name of the cloudflare module's table. The library default is sluis-<instance>-cloudflare. |
modules.outline.config.ports.dynamodb.tables.github |
string | — | The name of the github module's table. The library default is sluis-<instance>-github. |
modules.outline.config.ports.dynamodb.tables.google |
string | — | The name of the google module's table. The library default is sluis-<instance>-google. |
modules.outline.config.ports.dynamodb.tables.oidc |
string | — | The name of the oidc module's table. The library default is sluis-<instance>-oidc. |
modules.outline.config.ports.dynamodb.tables.outline |
string | — | The name of the outline module's table. The library default is sluis-<instance>-outline. |
modules.outline.config.ports.dynamodb.tables.slack |
string | — | The name of the slack module's table. The library default is sluis-<instance>-slack. |
modules.outline.config.preset |
one of server, k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid, k8s-aws, aws-eks | — | The adapters of a whole platform, one per concern: server (no AWS, no Kubernetes), k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid (sluis on Lambda, a cluster for the workloads), k8s-aws (sluis as a pod on Kubernetes with AWS storage: DynamoDB, S3, KMS-wrapped signing; SSM secrets, or OpenBao with adapters.secrets). aws-eks is the deprecated name of k8s-aws. Absent, the preset the platform answers lead to; with neither, the ports keys decide. adapters and the ports keys override single concerns. |
modules.outline.config.probes |
object | {"address":":7070"} |
The health listener. Separate from the service's own traffic, so that readiness is answerable when the service's listener is saturated, and so that a probe is not reachable from outside. |
modules.outline.config.probes.address |
string | required | host:port for /health/live and /health/ready. |
modules.outline.config.release |
string | "sluis" |
The name the installation's objects carry. It must be the release's full name: the controller reads the report and the records the service writes under it. |
modules.outline.config.secrets |
object | — | How the secrets this document names are delivered (truvity/policy config.md section 5). Absent is env. |
modules.outline.config.secrets.endpoint |
string | — | ssm: overrides the SSM address, for LocalStack. |
modules.outline.config.secrets.grace |
string | "24h" |
ssm: how long the previous value of a rotated client secret is still accepted: the document's previous revision, while the current one is younger than this (docs/decisions/0039-the-issuer-generates-confidential-client-secrets.md, the overlap). |
modules.outline.config.secrets.kmsKeyId |
string | — | ssm: the id, ARN or alias of the customer-managed KMS key the parameters the service itself writes (its credentials) are encrypted with. Unset, the AWS-managed alias/aws/ssm. The ssm secrets adapter's kmsKeyId setting; naming another there is refused. |
modules.outline.config.secrets.layout |
one of v5 | — | ssm, required: the storage layout of the installation's secrets, v5, the only one: the module first, <root>/internal/<module>/ and <root>/external/<module>/ (docs/decisions/0072-storage-layout-v5-module-first.md). Layout v4 was removed in v1.77.1 (an installation still on it migrates with sluis migrate v5 of v1.77.0 first), and with it the reading of an absent layout as v4. |
modules.outline.config.secrets.readCache |
string | "5m" |
ssm: how long a process keeps a document it read; a write drops it. 0s is off. SLUIS_SECRETS_READ_CACHE_TTL overrides. |
modules.outline.config.secrets.refresh |
string | "1m" |
ssm: how old a secret's copy may be before it is read again: a rotated secret reaches every instance within it. |
modules.outline.config.secrets.region |
string | — | ssm: the region. Unset follows the AWS SDK's own resolution. |
modules.outline.config.secrets.root |
string | — | file: the directory the secrets are mounted under. ssm: the installation's root, /sluis/ |
modules.outline.config.secrets.source |
one of env, file, ssm | "env" |
env: the variable SLUIS_SECRET_file: the file ssm: a SecureString in AWS SSM Parameter Store under layout): a name the service knows is read at its module's address (<root>/internal/oidc/state-secret, ...), any other at <root>/internal/config/<name>. |
modules.outline.config.tokenFile |
string | "/var/run/secrets/outline-roster/token" |
This pod's projected ServiceAccount token, presented to the console and read afresh on every call. |
modules.outline.enabled |
boolean | false |
Render this module's Deployment, ServiceAccount and ConfigMap (and, for a module that answers calls, its Service). |
modules.outline.image |
object | — | Overrides the chart's image for this module. Unset takes image (and image.perModule). |
modules.outline.image.repository |
string | — | |
modules.outline.image.tag |
string | — | |
modules.outline.podDisruptionBudget |
object | — | The module's PodDisruptionBudget: maxUnavailable 1 unless minAvailable is given (one of the two; a number at or above the replicas is refused). |
modules.outline.podDisruptionBudget.enabled |
boolean | true |
|
modules.outline.podDisruptionBudget.maxUnavailable |
integer or string | 1 |
A number of pods, or a percentage such as 50%. |
modules.outline.podDisruptionBudget.minAvailable |
integer or string | — | A number of pods, or a percentage such as 50%. |
modules.outline.replicas |
integer or null | — | Replicas. Unset: replicaCount for the issuer, 1 for another module. More than one controller replica needs the tick leases in a State they share. |
modules.outline.resources |
object | — | |
modules.outline.rpcPort |
integer | 8081 |
The port of the module's Service on /rpc, and of its listener. |
modules.outline.serviceAccount |
object | — | This module's own account. Name empty: serviceAccount.name when that is set). With irsa, each module but the issuer has its own awsRoleArn; the issuer takes the release's. |
modules.outline.serviceAccount.annotations |
object | — | |
modules.outline.serviceAccount.annotations.<name> |
string | — | |
modules.outline.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
modules.outline.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
modules.outline.serviceAccount.name |
string | — | |
modules.slack |
object | — | The Slack module (the controller), with a Service on /rpc for the issuer's console calls. |
modules.slack.audience |
string | — | The audience a call to this module carries: the module's name when empty. |
modules.slack.config |
object | — | The Slack module's document, without its apiVersion, over config.controllers.slack. Its schema is schemas/config/controller-slack.schema.json. |
modules.slack.config.adapters |
object | — | Names the adapter of single concerns, over the preset and the ports keys. The names and what each needs are in the matrix of docs/reference/sluis/adapters.md. |
modules.slack.config.adapters.audit |
object | — | The adapter for the audit sink, replacing the preset's. |
modules.slack.config.adapters.audit.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.audit.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.adapters.blobs |
object | — | The adapter for blobs, replacing the preset's. |
modules.slack.config.adapters.blobs.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.blobs.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.adapters.schedule |
object | — | The adapter for the schedule of passes, replacing the preset's. |
modules.slack.config.adapters.schedule.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.schedule.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.adapters.secrets |
object | — | The adapter for secrets (dynamic secrets), replacing the preset's. |
modules.slack.config.adapters.secrets.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.secrets.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.adapters.signing |
object | — | The adapter for token signing, replacing the preset's. |
modules.slack.config.adapters.signing.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.signing.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.adapters.state |
object | — | The adapter for state, sessions included, replacing the preset's. |
modules.slack.config.adapters.state.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.state.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.adapters.trigger |
object | — | The adapter for the "run a pass now" trigger, replacing the preset's. |
modules.slack.config.adapters.trigger.adapter |
string | required | The adapter's name, as the compatibility matrix lists it. |
modules.slack.config.adapters.trigger.settings |
object | — | The adapter's own settings (an object; the adapter refuses a key it does not know). |
modules.slack.config.audit |
object | — | The audit installation the controller records to, as its own workload. Unset only logs what it did. |
modules.slack.config.audit.tokenFile |
string | — | This workload's projected service-account token. |
modules.slack.config.audit.writer |
string | — | The installation's receiver. |
modules.slack.config.console |
object | — | How the controller proves itself to the console, when the pod's tokenFile is not the way. |
modules.slack.config.console.auth |
object | — | The proof. Absent, tokenFile. |
modules.slack.config.console.auth.aws |
object | — | The function role's AWS outbound web identity token (sts:GetWebIdentityToken), re-minted every four minutes. The console's issuer must federate the account, and its policy must declare an aws matcher for the role. |
modules.slack.config.console.auth.aws.audience |
string | required | The audience requested from STS. It must equal the issuer's console.awsAudience (default <issuerURL>/console), NOT the audience of its AWS federation file. |
modules.slack.config.consoleURL |
string | — | The console's API, which answers who holds a group. |
modules.slack.config.credentialsDir |
string | "/var/run/slack-roster/credentials" |
One file per connected workspace: the app's credentials and its bot token. |
modules.slack.config.github |
object | — | The GitHub module's routing (docs/decisions/0071). Unset keeps the module in this process. |
modules.slack.config.github.remote |
object | — | Where the GitHub module is when it is not this process: the calls to it go there. Set exactly one of function and url. Unset keeps the module in this process. |
modules.slack.config.github.remote.audience |
string | — | The audience of that token. The module's name, github, when unset. |
modules.slack.config.github.remote.function |
string | — | The module's Lambda function, name or ARN. It is invoked through the live-<class> alias of this process's caller class. |
modules.slack.config.github.remote.tokenFile |
string | — | Where the projected token is mounted. /var/run/secrets/sluis/github/token when unset. |
modules.slack.config.github.remote.url |
string | — | The module's Kubernetes Service. A call carries the pod's projected ServiceAccount token. |
modules.slack.config.github.serve |
object | — | Makes the GitHub module answer the issuer's calls on Kubernetes (docs/decisions/0071). Only the module's own document sets it. The module listens on address and accepts a call whose projected ServiceAccount token was minted for audience, checked with a TokenReview, and whose subject is one of issuers; any other call is a 401. On Lambda the function answers rpc events and IAM decides who may invoke it. Not with remote. Unset serves nothing. |
modules.slack.config.github.serve.address |
string | — | The listener, host:port; it also answers GET /healthz. :8081 when unset. |
modules.slack.config.github.serve.audience |
string | — | The audience a caller's token must be minted for. The module's name, github, when unset. |
modules.slack.config.github.serve.issuers |
array | required | The issuer's ServiceAccount, as system:serviceaccount:<namespace>:<name>. A call from it is both the issuer class (mint_installation) and the console class (the console methods); a token of any other subject is a 401. |
modules.slack.config.google |
object | — | The Google module's routing (docs/decisions/0071). Unset keeps the module in this process. |
modules.slack.config.google.remote |
object | — | Where the Google module is when it is not this process: the calls to it go there. Set exactly one of function and url. Unset keeps the module in this process. |
modules.slack.config.google.remote.audience |
string | — | The audience of that token. The module's name, google, when unset. |
modules.slack.config.google.remote.function |
string | — | The module's Lambda function, name or ARN. It is invoked through the live-<class> alias of this process's caller class. |
modules.slack.config.google.remote.tokenFile |
string | — | Where the projected token is mounted. /var/run/secrets/sluis/google/token when unset. |
modules.slack.config.google.remote.url |
string | — | The module's Kubernetes Service. A call carries the pod's projected ServiceAccount token. |
modules.slack.config.interval |
string | "15m" |
How long between passes. Positive. |
modules.slack.config.log |
object | — | Structured logging. One level for the whole service: per-package levels are deliberately not part of the contract. |
modules.slack.config.log.level |
one of debug, info, warn, error | "info" |
The lowest level that is written. |
modules.slack.config.platform |
object | — | What this installation has to build on. The answers pick a preset (the decision tree in docs/concepts/sluis/ports.md), and start refuses an adapter that needs an answer that is no. Absent, the ports keys decide and nothing is checked against the platform. |
modules.slack.config.platform.aws |
boolean | — | AWS is available: its credentials, DynamoDB, S3, SSM, KMS, SQS and EventBridge. |
modules.slack.config.platform.kubernetes |
boolean | — | A Kubernetes cluster is available. |
modules.slack.config.platform.openbao |
boolean | — | An OpenBao is available. |
modules.slack.config.platform.replicas |
integer | 1 |
How many replicas share this installation's state. Above 1 start refuses an adapter that keeps its data in the process (memory). |
modules.slack.config.platform.runtime |
one of kubernetes, lambda, process | — | Where sluis itself runs. Absent: kubernetes with a cluster, else lambda on AWS, else process. |
modules.slack.config.policy |
object | — | The policy document: the bindings are its slack table, and its controllers.slack section is what this controller may change. |
modules.slack.config.policy.file |
string | required | The policy document: the one canonical file sluisctl policy render writes (schemas/config/policy.schema.json). Read once, at start: a change is a new instance. |
modules.slack.config.ports |
object | — | The adapters behind the storage ports (docs/concepts/sluis/ports.md). |
modules.slack.config.ports.adapter |
one of legacy, memory, dynamodb | "legacy" |
legacy, the default, is deprecated since v1.74.0 and still ships: migrate with sluis migrate. It keeps state where it has always been kept: the namespace's ConfigMaps and Secrets and, when valkey is set, Valkey. memory keeps all of it in this process, which a restart loses: for a local run and the demonstration, and not with store: kubernetes or valkey. dynamodb keeps the same in one DynamoDB table (ports.dynamodb), with the platform's credentials, and takes its Blob from legacy unless ports.blob names its own. |
modules.slack.config.ports.blob |
object | — | Replaces the Blob port (status reports, directory snapshots) with an adapter of its own, whatever ports.adapter is. Absent, the Blob is ports.adapter's. |
modules.slack.config.ports.blob.adapter |
one of s3 | required | s3 keeps the blobs in an S3 bucket. |
modules.slack.config.ports.blob.s3 |
object | — | Where the S3 adapter keeps its objects. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here. |
modules.slack.config.ports.blob.s3.bucket |
string | required | The bucket. It must exist, with public access blocked. |
modules.slack.config.ports.blob.s3.checksum |
one of sha256, md5, none | "sha256" |
The integrity header of every upload: sha256 (x-amz-checksum-sha256, computed over the whole body and sent precomputed, never as an aws-chunked trailer), md5 (Content-MD5) or none, for a store that refuses SHA-256. AWS refuses a PutObject without one on an Object Lock bucket. |
modules.slack.config.ports.blob.s3.credentials |
object | — | Instead of a static document, sluis mints its own R2 credentials from a Cloudflare preset: the account's minter credential clones the preset's prototype, the credentials are renewed with a third of their lifetime left and minted again once after a 403. Exclusive with credentialsRef. Needs endpoint, the ssm secrets source, and the cloudflare section. |
modules.slack.config.ports.blob.s3.credentials.preset |
string | required | A key of cloudflare.presets that has an endpoint (an R2 preset). |
modules.slack.config.ports.blob.s3.credentialsRef |
string | — | Where the credentials for endpoint are, in the installation's secrets store (the ssm secrets source): the internal address, internal/<module>/<name>, of the s3-credentials/v1 document (access_key_id, secret_access_key) that holds static credentials, or external/cloudflare/<preset>, the cloudflare/v1 document the Cloudflare module rotates for an R2 preset with store: external (the access key is the token's id; it is read again with a third of its time left and after a 403). Read at start and again after an answer of 403, at most once a minute. Needs endpoint; region defaults to auto with it. Any other address is refused. This is the simple way and needs no cloudflare section in this document, so it is the one to use when the presets are another module's (cloudflare.remote). |
modules.slack.config.ports.blob.s3.endpoint |
string | — | Overrides the S3 address: LocalStack or an S3-compatible store (Cloudflare R2, MinIO). |
modules.slack.config.ports.blob.s3.kmsKey |
string | — | A KMS key id, ARN or alias for server-side encryption (SSE-KMS) of every write. Absent, the bucket's default encryption applies. |
modules.slack.config.ports.blob.s3.pathStyle |
boolean | — | Addresses the bucket in the path and not the host name, which LocalStack and most S3-compatible stores need. |
modules.slack.config.ports.blob.s3.prefix |
string | — | A key prefix inside the bucket, for an installation that shares it. |
modules.slack.config.ports.blob.s3.region |
string | — | The bucket's region. Absent, the SDK's own resolution (AWS_REGION). |
modules.slack.config.ports.dynamodb |
object | — | The DynamoDB tables of the dynamodb adapter: one table per module (tables, layout v5). Each has a string partition key pk, a string sort key sk and the TTL attribute expires. Credentials are the platform's (EKS Pod Identity, IRSA, a Lambda role) and are never configured here; an S3-compatible endpoint with no such identity names a credentials document by address (credentialsRef), never by value. |
modules.slack.config.ports.dynamodb.create |
boolean | false |
Create the table (on-demand, TTL on expires) at start when it is not there, for a test or a development installation. Off, the table must exist: production uses the one the infrastructure code made, and the role needs dynamodb:DescribeTable on it (layout v5: the readiness probe asks, not the start). |
modules.slack.config.ports.dynamodb.endpoint |
string | — | Overrides the DynamoDB address: LocalStack or DynamoDB Local. |
modules.slack.config.ports.dynamodb.region |
string | — | The table's region. Absent, the SDK's own resolution (AWS_REGION). |
modules.slack.config.ports.dynamodb.tables |
object | required | Layout v5 (docs/decisions/0072-storage-layout-v5-module-first.md): the table of each module, by module name. A process names its own module's table and the tables of the peers it reads; a module it does not name is not opened. The single table of layout v4 (table) was removed in v1.77.1. |
modules.slack.config.ports.dynamodb.tables.backup |
string | — | The name of the backup module's table. The library default is sluis-<instance>-backup. |
modules.slack.config.ports.dynamodb.tables.cloudflare |
string | — | The name of the cloudflare module's table. The library default is sluis-<instance>-cloudflare. |
modules.slack.config.ports.dynamodb.tables.github |
string | — | The name of the github module's table. The library default is sluis-<instance>-github. |
modules.slack.config.ports.dynamodb.tables.google |
string | — | The name of the google module's table. The library default is sluis-<instance>-google. |
modules.slack.config.ports.dynamodb.tables.oidc |
string | — | The name of the oidc module's table. The library default is sluis-<instance>-oidc. |
modules.slack.config.ports.dynamodb.tables.outline |
string | — | The name of the outline module's table. The library default is sluis-<instance>-outline. |
modules.slack.config.ports.dynamodb.tables.slack |
string | — | The name of the slack module's table. The library default is sluis-<instance>-slack. |
modules.slack.config.preset |
one of server, k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid, k8s-aws, aws-eks | — | The adapters of a whole platform, one per concern: server (no AWS, no Kubernetes), k8s-minimal, k8s-openbao, aws-serverless, aws-hybrid (sluis on Lambda, a cluster for the workloads), k8s-aws (sluis as a pod on Kubernetes with AWS storage: DynamoDB, S3, KMS-wrapped signing; SSM secrets, or OpenBao with adapters.secrets). aws-eks is the deprecated name of k8s-aws. Absent, the preset the platform answers lead to; with neither, the ports keys decide. adapters and the ports keys override single concerns. |
modules.slack.config.probes |
object | {"address":":7070"} |
The health listener. Separate from the service's own traffic, so that readiness is answerable when the service's listener is saturated, and so that a probe is not reachable from outside. |
modules.slack.config.probes.address |
string | required | host:port for /health/live and /health/ready. |
modules.slack.config.recordsDir |
string | "/var/run/slack-roster/workspaces" |
The console's records, mounted. |
modules.slack.config.release |
string | "sluis" |
The name the installation's objects carry. It must be the release's full name: the controller reads the report and the records the service writes under it. |
modules.slack.config.secrets |
object | — | How the secrets this document names are delivered (truvity/policy config.md section 5). Absent is env. |
modules.slack.config.secrets.endpoint |
string | — | ssm: overrides the SSM address, for LocalStack. |
modules.slack.config.secrets.grace |
string | "24h" |
ssm: how long the previous value of a rotated client secret is still accepted: the document's previous revision, while the current one is younger than this (docs/decisions/0039-the-issuer-generates-confidential-client-secrets.md, the overlap). |
modules.slack.config.secrets.kmsKeyId |
string | — | ssm: the id, ARN or alias of the customer-managed KMS key the parameters the service itself writes (its credentials) are encrypted with. Unset, the AWS-managed alias/aws/ssm. The ssm secrets adapter's kmsKeyId setting; naming another there is refused. |
modules.slack.config.secrets.layout |
one of v5 | — | ssm, required: the storage layout of the installation's secrets, v5, the only one: the module first, <root>/internal/<module>/ and <root>/external/<module>/ (docs/decisions/0072-storage-layout-v5-module-first.md). Layout v4 was removed in v1.77.1 (an installation still on it migrates with sluis migrate v5 of v1.77.0 first), and with it the reading of an absent layout as v4. |
modules.slack.config.secrets.readCache |
string | "5m" |
ssm: how long a process keeps a document it read; a write drops it. 0s is off. SLUIS_SECRETS_READ_CACHE_TTL overrides. |
modules.slack.config.secrets.refresh |
string | "1m" |
ssm: how old a secret's copy may be before it is read again: a rotated secret reaches every instance within it. |
modules.slack.config.secrets.region |
string | — | ssm: the region. Unset follows the AWS SDK's own resolution. |
modules.slack.config.secrets.root |
string | — | file: the directory the secrets are mounted under. ssm: the installation's root, /sluis/ |
modules.slack.config.secrets.source |
one of env, file, ssm | "env" |
env: the variable SLUIS_SECRET_file: the file ssm: a SecureString in AWS SSM Parameter Store under layout): a name the service knows is read at its module's address (<root>/internal/oidc/state-secret, ...), any other at <root>/internal/config/<name>. |
modules.slack.config.slack |
object | — | The Slack module's routing (docs/decisions/0071). Unset keeps the module in this process. |
modules.slack.config.slack.remote |
object | — | Where the Slack module is when it is not this process: the calls to it go there. Set exactly one of function and url. Unset keeps the module in this process. |
modules.slack.config.slack.remote.audience |
string | — | The audience of that token. The module's name, slack, when unset. |
modules.slack.config.slack.remote.function |
string | — | The module's Lambda function, name or ARN. It is invoked through the live-<class> alias of this process's caller class. |
modules.slack.config.slack.remote.tokenFile |
string | — | Where the projected token is mounted. /var/run/secrets/sluis/slack/token when unset. |
modules.slack.config.slack.remote.url |
string | — | The module's Kubernetes Service. A call carries the pod's projected ServiceAccount token. |
modules.slack.config.slack.serve |
object | — | Makes the Slack module answer the issuer's calls on Kubernetes (docs/decisions/0071). Only the module's own document sets it. The module listens on address and accepts a call whose projected ServiceAccount token was minted for audience, checked with a TokenReview, and whose subject is one of issuers; any other call is a 401. On Lambda the function answers rpc events and IAM decides who may invoke it. Not with remote. Unset serves nothing. |
modules.slack.config.slack.serve.address |
string | — | The listener, host:port; it also answers GET /healthz. :8081 when unset. |
modules.slack.config.slack.serve.audience |
string | — | The audience a caller's token must be minted for. The module's name, slack, when unset. |
modules.slack.config.slack.serve.issuers |
array | required | The issuer's ServiceAccount, as system:serviceaccount:<namespace>:<name>. A call from it is both the issuer class (mint_installation) and the console class (the console methods); a token of any other subject is a 401. |
modules.slack.config.tokenFile |
string | "/var/run/secrets/slack-roster/token" |
This pod's projected ServiceAccount token, presented to the console and read afresh on every call. |
modules.slack.enabled |
boolean | false |
Render this module's Deployment, ServiceAccount and ConfigMap (and, for a module that answers calls, its Service). |
modules.slack.image |
object | — | Overrides the chart's image for this module. Unset takes image (and image.perModule). |
modules.slack.image.repository |
string | — | |
modules.slack.image.tag |
string | — | |
modules.slack.podDisruptionBudget |
object | — | The module's PodDisruptionBudget: maxUnavailable 1 unless minAvailable is given (one of the two; a number at or above the replicas is refused). |
modules.slack.podDisruptionBudget.enabled |
boolean | true |
|
modules.slack.podDisruptionBudget.maxUnavailable |
integer or string | 1 |
A number of pods, or a percentage such as 50%. |
modules.slack.podDisruptionBudget.minAvailable |
integer or string | — | A number of pods, or a percentage such as 50%. |
modules.slack.replicas |
integer or null | — | Replicas. Unset: replicaCount for the issuer, 1 for another module. More than one controller replica needs the tick leases in a State they share. |
modules.slack.resources |
object | — | |
modules.slack.rpcPort |
integer | 8081 |
The port of the module's Service on /rpc, and of its listener. |
modules.slack.serviceAccount |
object | — | This module's own account. Name empty: serviceAccount.name when that is set). With irsa, each module but the issuer has its own awsRoleArn; the issuer takes the release's. |
modules.slack.serviceAccount.annotations |
object | — | |
modules.slack.serviceAccount.annotations.<name> |
string | — | |
modules.slack.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
modules.slack.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
modules.slack.serviceAccount.name |
string | — | |
nameOverride |
string | — | Replaces the chart name in the app.kubernetes.io/name label and in the controllers' selector labels. An installation migrating from the access-issuer chart sets it to access-issuer so the Deployments' immutable selectors are unchanged. |
networkPolicy |
object | — | |
networkPolicy.clients |
array | — | |
networkPolicy.egress |
object | — | Each module's egress: DNS, its peers, HTTPS and extra. A NetworkPolicy cannot name a host, so the providers, the cloud APIs and the API server are one HTTPS rule. |
networkPolicy.egress.dnsNamespace |
string | "kube-system" |
The namespace the cluster's DNS runs in. |
networkPolicy.egress.enabled |
boolean | true |
false renders ingress-only policies and leaves egress unrestricted. |
networkPolicy.egress.extra |
object | — | Rules appended to a module's egress, as NetworkPolicyEgressRule: the audit receiver, a collector, a secret store. |
networkPolicy.egress.extra.cloudflare |
array | — | |
networkPolicy.egress.extra.github |
array | — | |
networkPolicy.egress.extra.google |
array | — | |
networkPolicy.egress.extra.issuer |
array | — | |
networkPolicy.egress.extra.outline |
array | — | |
networkPolicy.egress.extra.slack |
array | — | |
networkPolicy.egress.https |
object | — | |
networkPolicy.egress.https.cidrs |
array | — | Where HTTPS may go. Empty renders no such rule. |
networkPolicy.egress.https.ports |
array | — | |
networkPolicy.enabled |
boolean | — | |
networkPolicy.gatewayNamespace |
string | — | |
nodeSelector |
object | — | |
podAnnotations |
object | — | |
policy |
object | — | The policy document, without its apiVersion, which the chart writes: rendered into the ConfigMap exchange, the catalogues from githubApps.catalogue and slackApps). Its schema is schemas/config/policy.schema.json. An access document or a directory of layers is rendered first: sluisctl policy render. |
renders |
one of app, alerts, dashboards | — | What this release renders: app, the service and the controllers (the default); alerts, only the alert rules; dashboards, only the Grafana folder and dashboards (grafana-operator objects). In the last two nothing else is rendered. |
replicaCount |
integer | — | |
resources |
object | — | |
restore |
object | — | The restore Job: for an administrator, off by default. Never a CronJob. It reads the document of backup.config and runs sluis restore start, with an account of its own, whose role may write every module's table. |
restore.activeDeadlineSeconds |
integer | 0 |
Stops the Job after this many seconds. 0: no limit. |
restore.backupId |
string | — | The backup to restore (sluis backup list). Exactly one of this and resume. |
restore.by |
string | — | Who asked, for the audit record. |
restore.confirm |
string | — | The installation's name, backup.config.instance: a restore overwrites a live installation, and the Job is refused unless this says which one. |
restore.enabled |
boolean | false |
Render one Job, named from backupId. Delete it before running the same restore again. |
restore.nodeSelector |
object | — | |
restore.note |
string | — | Why, for the audit record. |
restore.overwrite |
boolean | false |
Overwrite a destination that holds different data. Without it a non-empty destination is refused. |
restore.podAnnotations |
object | — | |
restore.resources |
object | — | |
restore.resume |
boolean | false |
Continue a restore that paused (sluis restore start --resume). No backupId. |
restore.serviceAccount |
object | — | The restore role's own account. Name empty: |
restore.serviceAccount.annotations |
object | — | |
restore.serviceAccount.annotations.<name> |
string | — | |
restore.serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role (as serviceAccount.awsIdentity). |
restore.serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
restore.serviceAccount.name |
string | — | |
restore.tolerations |
array | — | |
restore.ttlSecondsAfterFinished |
integer | 0 |
Remove the finished Job after this many seconds. 0: keep it. |
route |
object | — | |
route.certificate |
object | — | |
route.certificate.issuerKind |
one of Issuer, ClusterIssuer | — | |
route.certificate.issuerName |
string | — | |
route.certificate.privateKey |
object | — | |
route.certificate.privateKey.algorithm |
one of RSA, ECDSA | — | |
route.certificate.privateKey.encoding |
one of PKCS1, PKCS8 | — | |
route.certificate.privateKey.rotationPolicy |
one of Never, Always | — | |
route.certificate.privateKey.size |
one of 256, 384, 521, 2048, 3072, 4096 | — | |
route.gatewayClassName |
string | — | |
route.host |
string | — | |
route.parentRefs |
array | — | |
route.parentRefs[].group |
string | — | |
route.parentRefs[].kind |
string | — | |
route.parentRefs[].name |
string | required | |
route.parentRefs[].namespace |
string | — | |
route.parentRefs[].port |
integer | — | |
route.parentRefs[].sectionName |
string | — | |
route.rootRedirect |
string | — | Where a bare GET of the host root goes; empty serves 404. |
route.sharedWith |
array | — | |
secretEnv |
array | — | Environment variables from a Secret's keys: the holders of the secrets the config names (valkey.passwordEnv, oauthClient.secretEnv, adminPasswordEnv). A secret is never in config. |
secretEnv[].key |
string | required | The key in the Secret. |
secretEnv[].name |
string | required | The variable, as the config names it. |
secretEnv[].optional |
boolean | — | Start without it when the Secret or the key is absent. |
secretEnv[].secretName |
string | required | The Secret. |
secretManagers |
any | — | Removed in v1.30.0 — the console's secret-store view was removed. Setting this key fails the render with a clear message. See CHANGELOG.md and docs/decisions/0002-mission-boundary-tokens-and-memberships.md. |
secretMounts |
array | — | Secrets mounted read-only as directories, for a file the config names by path (oauthClient.idFile, oauthClient.secretFile). Each key is a file. |
secretMounts[].mountPath |
string | required | The directory it appears in. |
secretMounts[].secretName |
string | required | The Secret. |
secrets |
array | — | The secrets the config names, each one key of a Secret projected as the file |
secrets[].key |
string | required | |
secrets[].name |
string | required | The secret's name, as the config gives it: valkey/password. |
secrets[].secretName |
string | required | |
serviceAccount |
object | — | |
serviceAccount.annotations |
object | — | |
serviceAccount.annotations.<name> |
string | — | |
serviceAccount.awsIdentity |
one of pod-identity, irsa | — | How the pod gets its AWS role. pod-identity (EKS Pod Identity) renders nothing: the association is made outside the chart. irsa annotates the account with eks.amazonaws.com/role-arn: <awsRoleArn>, which it requires. |
serviceAccount.awsRoleArn |
string | — | The role's ARN, for awsIdentity: irsa. |
serviceAccount.name |
string | — | |
signingKey |
object | — | |
signingKey.additional |
array | — | |
signingKey.additional[].algorithm |
one of RSA, ECDSA | required | |
signingKey.additional[].duration |
string | — | |
signingKey.additional[].encoding |
one of PKCS1, PKCS8 | — | |
signingKey.additional[].issuerKind |
one of Issuer, ClusterIssuer | — | |
signingKey.additional[].issuerName |
string | — | |
signingKey.additional[].key |
string | — | |
signingKey.additional[].renewBefore |
string | — | |
signingKey.additional[].size |
one of 256, 384, 521, 2048, 3072, 4096 | required | |
signingKey.certificate |
object | — | |
signingKey.certificate.algorithm |
one of RSA, ECDSA | — | |
signingKey.certificate.duration |
string | — | |
signingKey.certificate.encoding |
one of PKCS1, PKCS8 | — | |
signingKey.certificate.issuerKind |
one of Issuer, ClusterIssuer | — | |
signingKey.certificate.issuerName |
string | — | |
signingKey.certificate.renewBefore |
string | — | |
signingKey.certificate.size |
one of 256, 384, 521, 2048, 3072, 4096 | — | |
signingKey.existingSecret |
string | — | |
signingKey.key |
string | — | |
signingKey.verifyOnly |
array | — | PUBLIC keys the chart mounts from a ConfigMap (they are not secret), one file each at /var/run/access-issuer/verify-keys/config.signingKey.verifyOnly[<index>].file: published in the JWKS and never signed with. A private key is refused. |
signingKey.verifyOnly[].pem |
string | required | A PEM public key, a certificate, or a JWK. |
slackApps |
array | — | Slack Apps declared as data, created and installed from the console. The service validates the whole catalogue again at start, and refuses an entry for a workspace the policy's slack.workspaces does not name. |
slackApps[].botScopes |
array | required | |
slackApps[].description |
string | — | |
slackApps[].id |
string | required | |
slackApps[].name |
string | — | |
slackApps[].push |
object | — | Copy this App's bot token to a secret store with an External Secrets PushSecret: that one key only, to the store and path named here. Absent pushes nothing. |
slackApps[].push.deletionPolicy |
one of None, Delete | — | |
slackApps[].push.refreshInterval |
string | — | |
slackApps[].push.remoteKey |
string | required | |
slackApps[].push.secretStore |
object | required | |
slackApps[].push.secretStore.kind |
one of SecretStore, ClusterSecretStore | — | |
slackApps[].push.secretStore.name |
string | required | |
slackApps[].workspace |
string | required | A key of the policy's slack.workspaces. |
slackState |
object | — | A recovery copy of the Slack state: see push. |
slackState.push |
object | — | Copy the credential of every connected Slack workspace, and the mirror of the records that say which workspaces and Slack Connect channels the console holds, to a secret store with an External Secrets PushSecret, for recovery: each whole Secret bundled under its own remote key (remoteKey for the credentials, recordsRemoteKey for the records), because the key names inside are not stable. Absent pushes nothing. deletionPolicy is deliberately not settable -- the case this exists for is the Secret going away. |
slackState.push.recordsRemoteKey |
string | required | |
slackState.push.refreshInterval |
string | — | |
slackState.push.remoteKey |
string | required | |
slackState.push.secretStore |
object | required | |
slackState.push.secretStore.kind |
one of SecretStore, ClusterSecretStore | — | |
slackState.push.secretStore.name |
string | required | |
telemetry |
object | — | The OpenTelemetry SDK environment on every pod of renders: app (ADR 0006). Nothing is rendered without otlp.endpoint. |
telemetry.otlp |
object | — | |
telemetry.otlp.endpoint |
string | — | OTEL_EXPORTER_OTLP_ENDPOINT: an http(s) URL naming the collector or gateway. Empty: nothing is exported and nothing is rendered. |
telemetry.otlp.extraEnv |
object | — | Other OpenTelemetry SDK variables, name to value. Every name starts with OTEL_ and none is OTEL_EXPORTER_OTLP_ENDPOINT (checked at render). |
telemetry.otlp.extraEnv.<name> |
string or number or boolean | — | |
telemetry.otlp.protocol |
one of http/protobuf, http/json, grpc | "http/protobuf" |
OTEL_EXPORTER_OTLP_PROTOCOL. |
tolerations |
array | — |
Routes: Configuration: the model.
Secret files¶
The chart projects each secrets entry, and in values mode each confidential client's Secret, as the file <name> in /var/run/sluis/secrets, mode 0440. The pod then runs as 65532:65532 with fsGroup: 65532, which also makes the other projected volumes group-readable.
What the chart refuses¶
charts/sluis/templates/_checks.tpl and _helpers.tpl hold the checks. Each message names the value to change.
| Area | Refused |
|---|---|
secrets |
A name declared twice; config.secrets other than {source: file, root: /var/run/sluis/secrets} when the chart projects secrets |
| Documents mode | documents.service without documents.policy, or the reverse; either beside policy, exchange.clusters or exchange.aws.accounts; a document that is not YAML or has the wrong apiVersion; an adapter settings.address that is not https; a setting that holds a credential value instead of a name; a secret name the documents use (a policy client's secret, the Google OAuth client of oauthClient.provider, any ...Secret field) that secrets does not declare, with secrets.source: file |
| Values mode | exchange.clusters, exchange.aws, githubApps.catalogue or slackApps set beside its policy.* counterpart |
| Controllers | No exchange.clusters; no console.mount; a consoleURL other than this release's own Service; enabledOrgs naming an organisation policy.github does not bind; enabledWorkspaces naming a workspace policy.slack.workspaces does not declare |
replicaCount |
Above 1 with a controller on, unless the State adapter is dynamodb |
push blocks |
Without config.store: kubernetes, a secretStore or a remoteKey; two pushes to the same remoteKey in one store; slackState.push without recordsRemoteKey |
| Route | config.secureCookies: false with route.host; a publicRootURL other than https://<route.host>, or a publicURL other than that plus console.mount, when console.mount is set; a parentRefs entry without name |
| Recovery | config.recovery.enabled without config.inCluster: true, recovery.serviceAccount or recovery.audience |
| Signing key | A key file (config.signingKey.file, signingKey.additional, signingKey.existingSecret) when signing is KMS; two keys for one algorithm; a private key in signingKey.verifyOnly |
telemetry.otlp |
An endpoint that is not http(s); extraEnv holding OTEL_EXPORTER_OTLP_ENDPOINT or a name not starting with OTEL_ |