@cratis/pi 7.126.0 → 7.127.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package/corpus/harnesses/copilot/instructions/profiles.instructions.md +3 -2
- package/package/corpus/harnesses/copilot/instructions/secrets.instructions.md +1 -1
- package/package/corpus/hooks/README.md +1 -1
- package/package/corpus/hooks/scripts/cratis-guard-secrets.sh +13 -2
- package/package/corpus/rules/profiles.md +3 -2
- package/package/corpus/rules/secrets.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/SKILL.md +1 -1
- package/package/corpus/skills/cratis-arc-authentication-authorization-and-identity/references/authproxy.md +26 -0
- package/package/corpus/skills/cratis-environments-and-secrets/LICENSE +9 -0
- package/package/corpus/skills/cratis-environments-and-secrets/SKILL.md +112 -0
- package/package/corpus/skills/cratis-environments-and-secrets/references/environment-file.md +48 -0
- package/package/corpus/skills/cratis-onboarding-runtime/LICENSE +9 -0
- package/package/corpus/skills/cratis-onboarding-runtime/SKILL.md +94 -0
- package/package/corpus/skills/cratis-onboarding-runtime/references/ante-onboarding-keys.md +31 -0
- package/package/corpus/skills/cratis-onboarding-runtime/references/performance.md +86 -0
- package/package/corpus/skills/cratis-screenplay-authentication-and-onboarding/LICENSE +9 -0
- package/package/corpus/skills/cratis-screenplay-authentication-and-onboarding/SKILL.md +111 -0
- package/package/corpus/skills/cratis-screenplay-authentication-and-onboarding/references/onboarding-directives.md +89 -0
- package/package/corpus/skills/cratis-screenplay-authentication-and-onboarding/verification.json +32 -0
- package/package/corpus/skills/cratis-screenplay-command-surface/references/policy-persona-seed.md +1 -0
- package/package/corpus/skills/cratis-screenplay-model-authoring/references/language-reference.md +1 -1
- package/package/corpus/skills/cratis-screenplay-model-review/SKILL.md +2 -0
- package/package/corpus/skills/cratis-screenplay-render-and-gap-fill/references/renderability-gate.md +8 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/neighbouring-skills.md +2 -0
- package/package/corpus/skills/cratis-screenplay-toolchain/references/screenplay-contract-exceptions.json +70 -0
- package/package/corpus/skills/cratis-showrunner-herald/LICENSE +9 -0
- package/package/corpus/skills/cratis-showrunner-herald/SKILL.md +106 -0
- package/package/corpus/skills/cratis-showrunner-herald/references/options.md +35 -0
- package/package/corpus/skills/cratis-showrunner-herald/references/templates-and-images.md +70 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/SKILL.md +5 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/rendered-application.md +39 -0
- package/package/corpus/skills/cratis-stage-rendering-and-sandbox/references/sandbox-and-specrunner.md +7 -0
- package/package/profile-catalog.json +6 -2
- package/package.json +1 -1
|
@@ -215,12 +215,12 @@ language policy always follows the consuming repository's `go.mod` minimum.
|
|
|
215
215
|
| `cratis/codescene` | Opt-in CodeScene Code Health change gates, refactoring, debt prioritization and risk-based testing; requires an account and available MCP tools; each user registers the MCP server (see below) |
|
|
216
216
|
| `cratis/playwright` | Opt-in Playwright browser automation MCP server declaration for exploratory checks; carries no skills or rules and each user registers the server (see below) |
|
|
217
217
|
| `cratis/studio` | Studio MCP safety guidance |
|
|
218
|
-
| `cratis/cli` | CLI operations |
|
|
218
|
+
| `cratis/cli` | CLI operations, project environments and secrets |
|
|
219
219
|
| `cratis/cli/terminal-workbench` | Human-operated terminal Workbench |
|
|
220
220
|
| `cratis/chronicle/mcp` | Chronicle MCP inspection and exact tool-effect guidance |
|
|
221
221
|
| `cratis/lens` | Lens browser extension |
|
|
222
222
|
| `cratis/screenplay` | Model-first event modeling: lifecycle, phase skills, toolchain, review, render and gap-fill, plus the whole `.play` language |
|
|
223
|
-
| `cratis/stage` | Stage rendering and sandbox |
|
|
223
|
+
| `cratis/stage` | Stage rendering and sandbox, onboarding runtime (Ante, Stage Manager) |
|
|
224
224
|
| `cratis/modeling/screenplay-stage` | Screenplay + Stage together |
|
|
225
225
|
|
|
226
226
|
### Code Health with CodeScene
|
|
@@ -302,6 +302,7 @@ and one phase skill, then the construct skill needed for syntax.
|
|
|
302
302
|
| `cratis-screenplay-read-surface` | `readmodel`, `query`, `screen`, name resolution |
|
|
303
303
|
| `cratis-screenplay-ui-composition` | `layout`, templates, `form`, `contribute`, `ui profile`, `theme`, `$strings`, `file` |
|
|
304
304
|
| `cratis-screenplay-captures-and-reactions` | The Change Data Capture Language, `reaction`, `trigger` |
|
|
305
|
+
| `cratis-screenplay-authentication-and-onboarding` | `authentication`, `onboarding`, and the environment keys derived from them |
|
|
305
306
|
| `cratis-screenplay-specifications` | Given/when/then and the reference execution |
|
|
306
307
|
| `cratis-screenplay-model-authoring` | Typed MCP authoring, model navigation/refactoring, compiler diagnostics, and source-versus-executable readiness |
|
|
307
308
|
|
|
@@ -17,7 +17,7 @@ Every line is tagged **[contract]** (binding) per the Three Levels of Authority
|
|
|
17
17
|
secrets; `kubectl get secret`; `kubectl config view --raw`; `env`, `printenv`, `export -p`
|
|
18
18
|
(including `env | …`); `docker inspect`; `gh secret`, `gh api …/secrets`, `gh auth token`;
|
|
19
19
|
`vault read`, `vault kv get`; cloud secret-manager reads; `pulumi … --show-secrets`;
|
|
20
|
-
reading kubeconfigs, `.env*` files, private keys or token files.
|
|
20
|
+
`cratis config get … --show-secret`; reading kubeconfigs, `.env*` files, private keys or token files.
|
|
21
21
|
- **[contract] Project the field you need and say which one:** `-o jsonpath='{.spec.containers[*].image}'`,
|
|
22
22
|
`-o custom-columns=…`, `kubectl get … -o name`, status fields, `kubectl logs`, `docker inspect --format`.
|
|
23
23
|
Read a `.env.example`, never the `.env`.
|
|
@@ -11,7 +11,7 @@ Three layers:
|
|
|
11
11
|
| Pattern pass | `PostToolUse` on a write | `scripts/cratis-pattern-scan.sh` | zero tokens until a match | appends a one-line reminder to context, never blocks |
|
|
12
12
|
| Hard block | `PreToolUse` on a write | `scripts/cratis-guard-writes.sh` | zero | exits **2** — the write does not happen |
|
|
13
13
|
| Hard block | `PreToolUse` on `Bash` | `scripts/cratis-guard-store-mutations.sh` | zero; parses only commands that mention `cratis` | exits **2** — the store-changing `cratis chronicle` command does not run |
|
|
14
|
-
| Hard block | `PreToolUse` on `Bash` | `scripts/cratis-guard-secrets.sh` | zero; parses only commands that mention a credential-bearing tool or file | exits **2** — a command that prints credentials (full `kubectl` specs and secrets, `env`/`printenv`, `docker inspect`, secret-manager reads, `.env`/kubeconfig/key files; also behind `/usr/bin/env`, `command`, attached options such as `-ePATTERN`, a bare `{.}` projection) does not run unless it projects a field; piped shells and recursive searches with no named file stay uncovered; see [`secrets.md`](../rules/secrets.md) |
|
|
14
|
+
| Hard block | `PreToolUse` on `Bash` | `scripts/cratis-guard-secrets.sh` | zero; parses only commands that mention a credential-bearing tool or file | exits **2** — a command that prints credentials (full `kubectl` specs and secrets, `env`/`printenv`, `docker inspect`, secret-manager reads, `cratis config get --show-secret`, `.env`/kubeconfig/key files; also behind `/usr/bin/env`, `command`, attached options such as `-ePATTERN`, a bare `{.}` projection) does not run unless it projects a field; piped shells and recursive searches with no named file stay uncovered; see [`secrets.md`](../rules/secrets.md) |
|
|
15
15
|
| Hard block | `PreToolUse` on `Bash` | `scripts/cratis-guard-pr-body.sh` | fetches shared rules only for `gh pr create/edit` | exits **2** for inline bodies, invalid notes or conflicting release labels; warns and allows when offline with no cache |
|
|
16
16
|
| Cleanup of delivered work | `PostToolUse` on `Bash` (`gh pr merge`, `git pull/merge/worktree`) and `SessionStart` (Pi: `tool_result` and `session_start`) | `scripts/cratis-cleanup-worktrees.sh --hook` | zero when the command is unrelated | never blocks; removes delivered worktrees and branches, reports what it kept |
|
|
17
17
|
| Quality gate (Claude) | `Stop` | `scripts/cratis-quality-gate.sh` | one build/test run, only when relevant files changed | exits **2** — the turn does not end |
|
|
@@ -35,7 +35,7 @@ command_text="$(hook_json "$input" '.tool_input.command')"
|
|
|
35
35
|
|
|
36
36
|
# Cheap exit for the overwhelming majority of shell commands, which mention none of these words.
|
|
37
37
|
case "$(printf '%s' "$command_text" | tr '[:upper:]' '[:lower:]')" in
|
|
38
|
-
*kubectl*|*printenv*|*env*|*docker*|*podman*|*"gh "*|*vault*|*pulumi*|*aws*|*"az "*|*gcloud*|*kubeconfig*|*.kube*|\
|
|
38
|
+
*kubectl*|*printenv*|*env*|*docker*|*podman*|*"gh "*|*vault*|*pulumi*|*show-secret*|*aws*|*"az "*|*gcloud*|*kubeconfig*|*.kube*|\
|
|
39
39
|
*export*|*declare*|*typeset*|*id_rsa*|*id_ed25519*|*id_ecdsa*|*id_dsa*|*.pem*|*.p12*|*.pfx*|*token*|*.netrc*|*.npmrc*|\
|
|
40
40
|
*credentials*|*.pgpass*|*secrets*) ;;
|
|
41
41
|
*) exit 0 ;;
|
|
@@ -397,7 +397,7 @@ function drop_redirects(A, s, n, k, m, w) {
|
|
|
397
397
|
}
|
|
398
398
|
return m
|
|
399
399
|
}
|
|
400
|
-
function analyze(A, s, n, w, b, k, names, p) {
|
|
400
|
+
function analyze(A, s, n, w, b, k, names, p, config, get, show) {
|
|
401
401
|
while (s <= n) {
|
|
402
402
|
w = A[s]; b = base(w)
|
|
403
403
|
if (is_assign(w)) { s++; continue }
|
|
@@ -446,6 +446,17 @@ function analyze(A, s, n, w, b, k, names, p) {
|
|
|
446
446
|
for (k = s + 1; k <= n; k++) if (A[k] ~ /^--show-secrets/) report("pulumi --show-secrets prints decrypted secrets", "pulumi config / pulumi stack output without --show-secrets (secrets stay masked)")
|
|
447
447
|
return
|
|
448
448
|
}
|
|
449
|
+
# `cratis config get` prints a secret as [secret]; --show-secret resolves it through the secrets provider.
|
|
450
|
+
if (b == "cratis") {
|
|
451
|
+
config = 0
|
|
452
|
+
for (k = s + 1; k <= n; k++) {
|
|
453
|
+
if (A[k] == "config") config = 1
|
|
454
|
+
else if (config && A[k] == "get") get = 1
|
|
455
|
+
if (A[k] ~ /^--show-secret/) show = 1
|
|
456
|
+
}
|
|
457
|
+
if (config && get && show) report("cratis config get --show-secret prints a decrypted secret", "cratis config get without --show-secret (a secret prints as [secret]); name the key in your report")
|
|
458
|
+
return
|
|
459
|
+
}
|
|
449
460
|
# A redirect is not a variable name: `printenv > f` and `export > f` still dump the whole environment.
|
|
450
461
|
if (b == "printenv" || b == "export" || b == "declare" || b == "typeset") n = drop_redirects(A, s, n)
|
|
451
462
|
if (b == "printenv") {
|
|
@@ -214,12 +214,12 @@ language policy always follows the consuming repository's `go.mod` minimum.
|
|
|
214
214
|
| `cratis/codescene` | Opt-in CodeScene Code Health change gates, refactoring, debt prioritization and risk-based testing; requires an account and available MCP tools; each user registers the MCP server (see below) |
|
|
215
215
|
| `cratis/playwright` | Opt-in Playwright browser automation MCP server declaration for exploratory checks; carries no skills or rules and each user registers the server (see below) |
|
|
216
216
|
| `cratis/studio` | Studio MCP safety guidance |
|
|
217
|
-
| `cratis/cli` | CLI operations |
|
|
217
|
+
| `cratis/cli` | CLI operations, project environments and secrets |
|
|
218
218
|
| `cratis/cli/terminal-workbench` | Human-operated terminal Workbench |
|
|
219
219
|
| `cratis/chronicle/mcp` | Chronicle MCP inspection and exact tool-effect guidance |
|
|
220
220
|
| `cratis/lens` | Lens browser extension |
|
|
221
221
|
| `cratis/screenplay` | Model-first event modeling: lifecycle, phase skills, toolchain, review, render and gap-fill, plus the whole `.play` language |
|
|
222
|
-
| `cratis/stage` | Stage rendering and sandbox |
|
|
222
|
+
| `cratis/stage` | Stage rendering and sandbox, onboarding runtime (Ante, Stage Manager) |
|
|
223
223
|
| `cratis/modeling/screenplay-stage` | Screenplay + Stage together |
|
|
224
224
|
|
|
225
225
|
### Code Health with CodeScene
|
|
@@ -301,6 +301,7 @@ and one phase skill, then the construct skill needed for syntax.
|
|
|
301
301
|
| `cratis-screenplay-read-surface` | `readmodel`, `query`, `screen`, name resolution |
|
|
302
302
|
| `cratis-screenplay-ui-composition` | `layout`, templates, `form`, `contribute`, `ui profile`, `theme`, `$strings`, `file` |
|
|
303
303
|
| `cratis-screenplay-captures-and-reactions` | The Change Data Capture Language, `reaction`, `trigger` |
|
|
304
|
+
| `cratis-screenplay-authentication-and-onboarding` | `authentication`, `onboarding`, and the environment keys derived from them |
|
|
304
305
|
| `cratis-screenplay-specifications` | Given/when/then and the reference execution |
|
|
305
306
|
| `cratis-screenplay-model-authoring` | Typed MCP authoring, model navigation/refactoring, compiler diagnostics, and source-versus-executable readiness |
|
|
306
307
|
|
|
@@ -16,7 +16,7 @@ Every line is tagged **[contract]** (binding) per the Three Levels of Authority
|
|
|
16
16
|
secrets; `kubectl get secret`; `kubectl config view --raw`; `env`, `printenv`, `export -p`
|
|
17
17
|
(including `env | …`); `docker inspect`; `gh secret`, `gh api …/secrets`, `gh auth token`;
|
|
18
18
|
`vault read`, `vault kv get`; cloud secret-manager reads; `pulumi … --show-secrets`;
|
|
19
|
-
reading kubeconfigs, `.env*` files, private keys or token files.
|
|
19
|
+
`cratis config get … --show-secret`; reading kubeconfigs, `.env*` files, private keys or token files.
|
|
20
20
|
- **[contract] Project the field you need and say which one:** `-o jsonpath='{.spec.containers[*].image}'`,
|
|
21
21
|
`-o custom-columns=…`, `kubectl get … -o name`, status fields, `kubectl logs`, `docker inspect --format`.
|
|
22
22
|
Read a `.env.example`, never the `.env`.
|
|
@@ -48,7 +48,7 @@ ingress above, otherwise configure a credential-validating scheme. The old
|
|
|
48
48
|
same host-wide flag. See [authentication](references/authentication.md).
|
|
49
49
|
Source: [secure defaults](https://github.com/Cratis/Arc/blob/main/Documentation/upgrading/secure-defaults.mdx).
|
|
50
50
|
|
|
51
|
-
Cratis AuthProxy is the ingress that meets these obligations for Cratis applications. Read [AuthProxy](references/authproxy.md) when the application is deployed behind it (header contract, `/.cratis/me` fail-closed verification, tenant headers).
|
|
51
|
+
Cratis AuthProxy is the ingress that meets these obligations for Cratis applications. Read [AuthProxy](references/authproxy.md) when the application is deployed behind it (header contract, `/.cratis/me` fail-closed verification, tenant headers, and starting it from a Screenplay model's provider list and a Cratis environment).
|
|
52
52
|
|
|
53
53
|
## Identity details — what the frontend is told
|
|
54
54
|
|
|
@@ -49,6 +49,32 @@ is a crawler policy, not authorization. Invitation error-page tokens
|
|
|
49
49
|
letters, digits and `._+-@`; do not assume these placeholders always contain text.
|
|
50
50
|
Signed-in `/register` forwarding needs no host workaround.
|
|
51
51
|
|
|
52
|
+
## Starting AuthProxy from a Screenplay application's contract
|
|
53
|
+
|
|
54
|
+
Requires AuthProxy 2.40.0 or later for `Cratis:AuthProxy:Application`; an older image ignores it and starts with no providers.
|
|
55
|
+
|
|
56
|
+
AuthProxy can start from two inputs: the **provider list** of a Screenplay model (kind and identity per provider) and the **values of a Cratis environment**. It translates them onto its ordinary `Cratis:AuthProxy` options, so an application behind it trusts the proxy exactly as described above. The model never carries provider configuration; see `cratis-screenplay-authentication-and-onboarding` for the keys and `cratis-environments-and-secrets` for the values.
|
|
57
|
+
|
|
58
|
+
```json
|
|
59
|
+
{
|
|
60
|
+
"Cratis": { "AuthProxy": { "Application": {
|
|
61
|
+
"EnvironmentName": "production",
|
|
62
|
+
"Providers": [
|
|
63
|
+
{ "Kind": "EntraId", "Identity": "EntraId" },
|
|
64
|
+
{ "Kind": "OpenId", "Identity": "Partner" }
|
|
65
|
+
]
|
|
66
|
+
} } }
|
|
67
|
+
}
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
- A provider's `Kind` is `EntraId`, `GitHub`, `Google`, `Apple` or `OpenId`; `Identity` is the model's alias, otherwise the provider name, unique ignoring case. The identity is also the scheme (lowercase, spaces to hyphens), so the callback is `/signin-<scheme>`.
|
|
71
|
+
- Required keys per kind: `clientId` and `clientSecret` for all; plus `tenantId` for `EntraId` and `authority` for `OpenId`. Each is addressed as `authentication.providers.<Identity>.<key>`.
|
|
72
|
+
- The contract cannot be combined with providers configured directly under `Authentication:OidcProviders` or `OAuthProviders`; AuthProxy refuses to start.
|
|
73
|
+
- A missing required key stops AuthProxy before it listens (exit code 78), naming the key, provider and environment, never a value.
|
|
74
|
+
- **Secrets are never read from arguments and never logged.** A key resolves from `Cratis:AuthProxy:Application:Environment:<key>`, then the same key with `_FILE` appended (a path to a file holding the value), then a file named exactly `<key>` in `SecretsDirectory`. Mount secrets as files and point `SecretsDirectory` at the folder; do not put a secret in an environment variable or an image.
|
|
75
|
+
- `Application:Development=true` allows HTTP only on loopback addresses; every other URL must be HTTPS. Never set it outside local development.
|
|
76
|
+
- With `Application:Onboarding=true`, supply the `onboarding.*` keys for the application's own Ante and every provider also gets invitation completion; see `cratis-onboarding-runtime`.
|
|
77
|
+
|
|
52
78
|
## Tenants and services
|
|
53
79
|
|
|
54
80
|
AuthProxy resolves the tenant through ordered strategies under `Cratis:AuthProxy:TenantResolutions` (`Host`, `Claim`, `Route`, `Specified`, `Default`, `SubHost`, `Selection`). The result reaches the backend as `x-cratis-tenant-id`, which is Arc's default tenant header, so an Arc application behind AuthProxy needs no tenancy configuration and the `UseHeaderTenancy("Tenant-ID")` workaround seen in older applications can be removed.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
Licensed under the MIT license. See LICENSE file in the canonical Cratis/AI repository for the full license text.
|
|
3
|
+
|
|
4
|
+
Third-party notices
|
|
5
|
+
|
|
6
|
+
This skill adapts material from agentic-engineer by Martin Dilger and Nebulit GmbH
|
|
7
|
+
(https://github.com/Nebulit-GmbH/agentic-engineer, commit 07b0f30648d663cb588d7e2c7aa031af9dfc21f2;
|
|
8
|
+
https://nebulit.de), used with the explicit consent of Martin Dilger and Nebulit GmbH. The adapted
|
|
9
|
+
material remains credited to Martin Dilger and Nebulit GmbH.
|
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-environments-and-secrets
|
|
3
|
+
description: Use when a Cratis project needs named environments, per-environment configuration values or secrets with `cratis env` and `cratis config`, or when a Screenplay model's environment keys must be filled. Not for Chronicle server contexts or for authoring the model.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Cratis environments and secrets
|
|
8
|
+
|
|
9
|
+
A Screenplay model is the same in every environment. What it needs to run (a client id, an SMTP
|
|
10
|
+
host, a signing key) is not. A project keeps that in **named environments**, one committed file
|
|
11
|
+
per environment next to the model, in the way a Pulumi project has stacks. Which keys a model
|
|
12
|
+
needs is derived from its declarations: see
|
|
13
|
+
[cratis-screenplay-authentication-and-onboarding](../cratis-screenplay-authentication-and-onboarding/SKILL.md).
|
|
14
|
+
|
|
15
|
+
**Requires** `cratis` 3.114.0 or later for `cratis env` and `cratis config` (`cratis --version`,
|
|
16
|
+
and `which -a cratis` for a shadowing copy). The commands do not exist in older releases.
|
|
17
|
+
|
|
18
|
+
This is not a Chronicle server context: `cratis context` and `-e/--event-store` on `chronicle`
|
|
19
|
+
commands belong to `cratis-chronicle-cli-operations`.
|
|
20
|
+
|
|
21
|
+
## The secrets contract
|
|
22
|
+
|
|
23
|
+
This skill applies the always-on [secrets rule](../../rules/secrets.md); read it first. For this
|
|
24
|
+
CLI it means:
|
|
25
|
+
|
|
26
|
+
- **A secret enters only through stdin or the hidden prompt.** Never as an argument (it lands in shell history and the transcript).
|
|
27
|
+
- **An agent never runs `cratis config get <key> --show-secret`** and never prints a secret by
|
|
28
|
+
any other route. Without the flag a secret prints as `[secret]`, which is the form to use.
|
|
29
|
+
- **An agent does not receive the value to set.** When a secret is needed and the person has not
|
|
30
|
+
provided it through a channel the agent cannot read, ask them to run the `--secret` command in
|
|
31
|
+
their own terminal. Do not ask them to paste it into the chat.
|
|
32
|
+
- **A passphrase is not a value to hold.** It comes from `CRATIS_PASSPHRASE`, the file named by
|
|
33
|
+
`CRATIS_PASSPHRASE_FILE`, or the hidden prompt. Never write one to a file in the repository,
|
|
34
|
+
and never export one inline in a command.
|
|
35
|
+
|
|
36
|
+
## Files and selection
|
|
37
|
+
|
|
38
|
+
Each environment is `.cratis/environments/<name>.yaml`; a name is a safe file name such as
|
|
39
|
+
`development`, `staging` or `customer-x`. Entries are a plain `key: value`, a `secure: <base64>`
|
|
40
|
+
secret encrypted by the passphrase provider (safe to commit), or a `ref:` to a vault. The file
|
|
41
|
+
never holds a clear-text secret. Read [environment file](references/environment-file.md) for the
|
|
42
|
+
exact shape.
|
|
43
|
+
|
|
44
|
+
The environment in effect is, in order: `--environment <name>` (`-e` on `env` and `config`),
|
|
45
|
+
`CRATIS_ENVIRONMENT`, the user's selection in `.cratis/local/selected-environment` (not committed), then
|
|
46
|
+
`development`. On Chronicle commands `-e` means `--event-store`; use `--environment` there.
|
|
47
|
+
|
|
48
|
+
## Commands
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
cratis env init # creates "development"
|
|
52
|
+
cratis env init production --secrets-provider azurekeyvault://<vault>
|
|
53
|
+
cratis env select production
|
|
54
|
+
cratis env ls
|
|
55
|
+
cratis config set auth:clientId <client-id>
|
|
56
|
+
cratis config set smtp:password --secret # reads stdin or a hidden prompt
|
|
57
|
+
cratis config get smtp:password # [secret]
|
|
58
|
+
cratis config # list; secrets show as [secret]
|
|
59
|
+
cratis config --missing ./model # keys the model needs and the environment lacks
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
| Command | Purpose |
|
|
63
|
+
|---|---|
|
|
64
|
+
| `cratis env init [name]` | Create an environment; `--secrets-provider` picks where secrets live. |
|
|
65
|
+
| `cratis env select <name>` / `ls` / `rm <name>` | Select for this user, list (the one in effect is marked), remove (confirms; `--yes` skips). |
|
|
66
|
+
| `cratis env change-secrets-provider <uri>` | Move every secret to another provider; the file never holds clear text in between. |
|
|
67
|
+
| `cratis env change-passphrase` | Re-encrypt every secret under a new passphrase and salt. |
|
|
68
|
+
| `cratis config set <key> <value>` | Set a plain value. |
|
|
69
|
+
| `cratis config set <key> --secret` | Set a secret. |
|
|
70
|
+
| `cratis config get <key>` / `rm <key>` | Read (secrets masked) / remove (also from the vault). |
|
|
71
|
+
| `cratis config [--missing <path>]` | List keys, or the keys a model needs that are absent. |
|
|
72
|
+
|
|
73
|
+
All accept `-o json`. Exit codes: `0` success, `1` not found, `4` authentication failed (wrong
|
|
74
|
+
passphrase), `5` validation, including any key missing under `--missing`.
|
|
75
|
+
|
|
76
|
+
## Choosing a secrets provider
|
|
77
|
+
|
|
78
|
+
Default to **passphrase** for a project with one team and a committed environment file. Choose a
|
|
79
|
+
vault when secrets must not travel with the repository or are shared with a cluster.
|
|
80
|
+
|
|
81
|
+
| Provider | Use when | Credentials come from |
|
|
82
|
+
|---|---|---|
|
|
83
|
+
| `passphrase` (default) | Secrets are committed encrypted (AES-256-GCM, key derived per environment). | `CRATIS_PASSPHRASE`, `CRATIS_PASSPHRASE_FILE` or a prompt. |
|
|
84
|
+
| `azurekeyvault://<vault>` | The team already runs Azure Key Vault. | `DefaultAzureCredential` (Azure CLI login, managed or workload identity). |
|
|
85
|
+
| `hashivault://<address>/<mount>[/<path>]` | The team runs HashiCorp Vault KV v2. `hashivault+http://` is for a development server. | `VAULT_TOKEN`, or `VAULT_ROLE_ID` and `VAULT_SECRET_ID`, or `VAULT_K8S_ROLE`. |
|
|
86
|
+
|
|
87
|
+
`cratis run` on a model with `authentication` resolves the selected environment (or `-e <name>`)
|
|
88
|
+
before starting Docker, hands the provider and onboarding values to the AuthProxy and Ante
|
|
89
|
+
containers, and stops with exit `5` listing the missing keys, never their values. A mail
|
|
90
|
+
server is optional: without `onboarding.email.server.host`, emails are written as `.eml` files.
|
|
91
|
+
Requires cratis CLI 3.116.0 (`cratis --version`); older CLIs run the Stage alone and play a persona.
|
|
92
|
+
|
|
93
|
+
## Pitfalls
|
|
94
|
+
|
|
95
|
+
- Setting a secret with `cratis config set smtp:password <value>` stores a plain value and leaks it. Always add `--secret` and pipe or prompt.
|
|
96
|
+
- Committing a `.cratis/local/` folder: it holds the personal selection and is git-ignored by `cratis init` and `cratis env select`.
|
|
97
|
+
- Wrong passphrase is exit `4` before anything is decrypted; do not retry it in a loop.
|
|
98
|
+
- `cratis config --missing` on a model that does not compile exits `5` and names the first errors; fix the model first.
|
|
99
|
+
- A key added to the model later is missing from existing environments; re-run `--missing` per environment.
|
|
100
|
+
|
|
101
|
+
## Verify
|
|
102
|
+
|
|
103
|
+
1. `cratis env ls` marks the environment you intend; `cratis config -e <name>` lists the expected keys.
|
|
104
|
+
2. `cratis config --missing <model-folder> -e <name>` exits `0` (`echo $?`).
|
|
105
|
+
3. `git diff` on `.cratis/environments/` shows only plain values, `secure:` or `ref:` entries, and no clear-text secret.
|
|
106
|
+
4. No command in the session used `--show-secret`, and no secret appears in the transcript.
|
|
107
|
+
|
|
108
|
+
## Route near misses
|
|
109
|
+
|
|
110
|
+
- Chronicle server contexts and operations: `cratis-chronicle-cli-operations`.
|
|
111
|
+
- The model's `authentication` and `onboarding` blocks and their keys: `cratis-screenplay-authentication-and-onboarding`.
|
|
112
|
+
- Running the application with the resolved values: `cratis-onboarding-runtime` (cluster) and `cratis-stage-rendering-and-sandbox`.
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
# Environment file
|
|
2
|
+
|
|
3
|
+
```yaml
|
|
4
|
+
secretsProvider: passphrase
|
|
5
|
+
encryptionSalt: <base64>
|
|
6
|
+
encryption:
|
|
7
|
+
kdf: pbkdf2-sha256
|
|
8
|
+
iterations: 600000
|
|
9
|
+
check: <base64>
|
|
10
|
+
config:
|
|
11
|
+
auth:clientId: <client-id>
|
|
12
|
+
smtp:host: mail.example.com
|
|
13
|
+
smtp:password:
|
|
14
|
+
secure: <base64>
|
|
15
|
+
signing:key:
|
|
16
|
+
ref: <vault reference>
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
| Entry | Meaning |
|
|
20
|
+
|---|---|
|
|
21
|
+
| `key: value` | A plain value. |
|
|
22
|
+
| `key: { secure: <base64> }` | A secret encrypted by the passphrase provider; bound to its key, so moving the ciphertext to another key fails. Safe to commit. |
|
|
23
|
+
| `key: { ref: <name> }` | A secret kept in Azure Key Vault or HashiCorp Vault. The file holds only the reference. |
|
|
24
|
+
|
|
25
|
+
`secretsProvider`, `encryptionSalt` and `encryption` describe where secrets live. The salt is per
|
|
26
|
+
environment, so two environments with one passphrase get different ciphertext. Do not edit these
|
|
27
|
+
fields by hand; use `cratis env change-passphrase` or `change-secrets-provider`.
|
|
28
|
+
|
|
29
|
+
## Vault storage
|
|
30
|
+
|
|
31
|
+
- Azure Key Vault: secrets named `cratis-<environment>-<key>` with a short hash suffix; the file holds the name as `ref:`.
|
|
32
|
+
- HashiCorp Vault: KV v2 at `<path>/<environment>/<key>` (the path defaults to `cratis`); the file holds that path as `ref:`.
|
|
33
|
+
- `VAULT_AUTH_MOUNT` overrides the auth method mount and `VAULT_NAMESPACE` sets the Vault namespace.
|
|
34
|
+
|
|
35
|
+
## Reading environments from code
|
|
36
|
+
|
|
37
|
+
The `Cratis.Environments` package reads the same files, so other tools resolve values and
|
|
38
|
+
secrets exactly as the CLI does.
|
|
39
|
+
|
|
40
|
+
```csharp
|
|
41
|
+
var environments = ProjectEnvironments.Discover(Directory.GetCurrentDirectory());
|
|
42
|
+
var selected = environments.Resolve(explicitName: null);
|
|
43
|
+
var environment = ProjectEnvironment.Open(environments, selected.Name, PassphraseSources.FromEnvironment());
|
|
44
|
+
|
|
45
|
+
var clientId = await environment.GetValueAsync("auth:clientId");
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Keep a resolved secret in memory only; never log it or write it to a file the repository tracks.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
Licensed under the MIT license. See LICENSE file in the canonical Cratis/AI repository for the full license text.
|
|
3
|
+
|
|
4
|
+
Third-party notices
|
|
5
|
+
|
|
6
|
+
This skill adapts material from agentic-engineer by Martin Dilger and Nebulit GmbH
|
|
7
|
+
(https://github.com/Nebulit-GmbH/agentic-engineer, commit 07b0f30648d663cb588d7e2c7aa031af9dfc21f2;
|
|
8
|
+
https://nebulit.de), used with the explicit consent of Martin Dilger and Nebulit GmbH. The adapted
|
|
9
|
+
material remains credited to Martin Dilger and Nebulit GmbH.
|
|
@@ -0,0 +1,94 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: cratis-onboarding-runtime
|
|
3
|
+
description: Use when running or deploying the onboarding of a Screenplay application, meaning configuring the application's Ante from the onboarding contract or declaring a Showrunner Stage Manager `Performance` that runs the application with its AuthProxy and Ante. Not for authoring the model or for Ante used by a host product.
|
|
4
|
+
license: MIT
|
|
5
|
+
---
|
|
6
|
+
|
|
7
|
+
# Onboarding runtime: Ante and Stage Manager
|
|
8
|
+
|
|
9
|
+
A Screenplay model with `authentication` and `onboarding` is carried out by three runtime parts
|
|
10
|
+
that read one contract, produced from the model and a Cratis environment:
|
|
11
|
+
|
|
12
|
+
| Part | Does | Contract |
|
|
13
|
+
|---|---|---|
|
|
14
|
+
| **AuthProxy** | The only public entry point; signs people in with the model's providers. | `Cratis:AuthProxy:Application` (see the AuthProxy reference of `cratis-arc-authentication-authorization-and-identity`). |
|
|
15
|
+
| **Ante** | **One per application.** Signs invitation tokens, serves the lobby, records acceptance and legal terms, publishes to its outbox. | `Ante:Onboarding:*`. |
|
|
16
|
+
| **Herald** | Sends the invitation and welcome emails from the application (the declined template waits for an Ante outcome). | `cratis-showrunner-herald`. |
|
|
17
|
+
|
|
18
|
+
Nobody writes the equivalent `Ante:*` or `Cratis:AuthProxy:*` keys by hand for a Screenplay
|
|
19
|
+
application. The model supplies structure (providers, personas, invitation types, legal files);
|
|
20
|
+
the **environment** supplies every value and secret (`cratis-environments-and-secrets`).
|
|
21
|
+
|
|
22
|
+
**Requires** Ante 1.5.0 or later for `Ante:Onboarding:*`, AuthProxy 2.40.0 or later for
|
|
23
|
+
`Cratis:AuthProxy:Application`, and Showrunner 1.11.0 or later for the `Performance` resource.
|
|
24
|
+
|
|
25
|
+
## Who owns what
|
|
26
|
+
|
|
27
|
+
Ante owns token signing, the lobby, local acceptance, legal terms presented from files, and the
|
|
28
|
+
persona and invitation-type checks. The **application** owns the persona list (the model), who is
|
|
29
|
+
invited, link delivery, membership and provisioning. Ante sends no email: the application sends
|
|
30
|
+
the invitation link through Herald using the `InvitationTokenIssued` token. Every accepted fact
|
|
31
|
+
(`InvitationToJoinTenantAccepted`, `InvitationToCreateTenantAccepted`,
|
|
32
|
+
`OrganizationRegistrationCompleted`, `LegalTermsAccepted`) means **published to Ante's outbox, not
|
|
33
|
+
provisioned**: make provisioning idempotent by event source id and event kind. Ante does not know
|
|
34
|
+
what a persona may do; it validates grantable personas against the configured list only.
|
|
35
|
+
|
|
36
|
+
## Ante's onboarding contract
|
|
37
|
+
|
|
38
|
+
Set `Ante:Onboarding:Enabled=true` to apply it. While `false` or absent every `Ante:Onboarding:*`
|
|
39
|
+
key is ignored. When enabled, each value it carries wins over the ordinary key it maps to,
|
|
40
|
+
including values from `appsettings.json`. Read [Ante onboarding keys](references/ante-onboarding-keys.md)
|
|
41
|
+
for the table before configuring anything.
|
|
42
|
+
|
|
43
|
+
- `HostStore` is the application's own Chronicle store, the only host store Ante observes. The application appends `UserInvitedToJoinTenant` or `UserInvitedToCreateTenant` to that store's outbox.
|
|
44
|
+
- `SignUp` is `CreateTenant` (default; self-service registration may create a tenant) or `JoinTenant` (`/register` closed; invitation only). This is the model's `signup` line.
|
|
45
|
+
- `InvitationTypes` and `Personas` are runtime checks: an invitation of a disallowed type is rejected with `InvitationTypeNotAllowed`, one granting a persona outside the list with `PersonaNotGrantable`, and no token is issued either way. Validate against the model's persona list in the application first; Ante is the second line of defense. Observe generation 4 of `InvitationRejected`.
|
|
46
|
+
- Legal terms are files in a mounted folder (`terms.md`, `privacy.md`). The version is a content hash, so editing either file requires everyone onboarding afterwards to accept again. Archive each version for consent audit; the bodies live in your files.
|
|
47
|
+
- **Secrets** (the signing private key, pinned attestation public keys) arrive only as mounted files or standard configuration, never on the command line; Ante logs no value.
|
|
48
|
+
|
|
49
|
+
## Development mode is for local runs only
|
|
50
|
+
|
|
51
|
+
`Ante:Onboarding:Development:Enabled=true` generates a 2048-bit RSA signing key per data volume and
|
|
52
|
+
needs no secret. Ante refuses to start when the environment name is production-like (`Production`,
|
|
53
|
+
`Prod`, `Live`, `Staging`, `Stage`, `Preprod`), in a Kubernetes pod, or when a configured URL is not
|
|
54
|
+
loopback. Never copy a development key to another environment, and leave `Secrets:SigningKeyFile` out of a development run.
|
|
55
|
+
|
|
56
|
+
Locally, `cratis run` on a model with `onboarding` starts Ante this way: `ASPNETCORE_ENVIRONMENT`
|
|
57
|
+
is `Development` and `Ante:Onboarding:Development:Enabled` is `true`, so Ante generates its signing
|
|
58
|
+
key into a folder that lives only for the run. It shares AuthProxy's network stack, so AuthProxy
|
|
59
|
+
reaches it on loopback, and the lobby is served through AuthProxy. Nothing from a local run is
|
|
60
|
+
trusted by another run or cluster.
|
|
61
|
+
|
|
62
|
+
## Stage Manager `Performance`
|
|
63
|
+
|
|
64
|
+
A `Performance` (`showrunner.cratis.io/v1alpha1`) runs one application in one Cratis environment,
|
|
65
|
+
with its AuthProxy when the application has `authentication` and its own Ante when it has
|
|
66
|
+
`onboarding`. Read [Performance resource](references/performance.md) to write or review the spec.
|
|
67
|
+
|
|
68
|
+
- The environment file is supplied as a ConfigMap key (the file `cratis` keeps in `.cratis/environments/<name>.yaml`); a passphrase environment names a Secret for the passphrase. Vault access belongs to the operator's identity, set in the chart, not the Performance.
|
|
69
|
+
- **A resolved value reaches a container only as a file in a mounted Secret volume**: never an environment variable, a ConfigMap, the status or the operator log.
|
|
70
|
+
- Nothing is created until everything is in hand. A missing environment key makes the phase `Blocked` and lists the keys in `status.missingEnvironmentKeys`; running Deployments are left alone.
|
|
71
|
+
- AuthProxy is the only ingress target; the application and Ante are ClusterIP Services behind it.
|
|
72
|
+
- The operator generates and rotates the invitation and attestation signing keys (`spec.signingKeys.rotation`) and derives the issuers, audiences and URLs, so none of them is written twice.
|
|
73
|
+
|
|
74
|
+
## Pitfalls
|
|
75
|
+
|
|
76
|
+
- Treating `Accepted` as provisioned: provisioning is the application's, and must be idempotent.
|
|
77
|
+
- Setting a signing key or provider secret as an environment variable in a manifest: use the mounted files.
|
|
78
|
+
- Two Ante instances for one application, or one Ante shared by several Performances: one Ante per Performance, with its own event store (`ante-<name>` by default).
|
|
79
|
+
- Using development mode in a shared cluster: Ante refuses; do not work around the guard.
|
|
80
|
+
|
|
81
|
+
## Verify
|
|
82
|
+
|
|
83
|
+
1. The model compiles and `screenplay environment <folder>` lists the keys; `cratis config --missing <folder> -e <name>` exits `0`.
|
|
84
|
+
2. `kubectl get performance <name> -o jsonpath='{.status.phase}'` is `Ready`; `-o jsonpath='{.status.missingEnvironmentKeys}'` is empty.
|
|
85
|
+
3. An invitation for a persona outside the model is rejected with `PersonaNotGrantable` and issues no token.
|
|
86
|
+
4. No secret value appears in a manifest, the status, a log or the transcript (`kubectl get -o json` on pods or secrets is forbidden by the secrets rule; project fields instead).
|
|
87
|
+
|
|
88
|
+
## Route near misses
|
|
89
|
+
|
|
90
|
+
- The model's `onboarding` block and environment keys: `cratis-screenplay-authentication-and-onboarding`.
|
|
91
|
+
- Environment commands and secrets providers: `cratis-environments-and-secrets`.
|
|
92
|
+
- Sending the emails: `cratis-showrunner-herald`.
|
|
93
|
+
- Ante used by a host product, not a Screenplay application: Ante's own documentation; this corpus does not cover it.
|
|
94
|
+
- Chronicle itself in a cluster: `cratis-chronicle-hosting`.
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
# Ante onboarding keys
|
|
2
|
+
|
|
3
|
+
Configuration keys under `Ante:Onboarding:` when `Enabled` is `true`. Each value maps onto the
|
|
4
|
+
ordinary key shown and wins over it. In environment-variable form use `__` for `:`.
|
|
5
|
+
|
|
6
|
+
| Key | Type | Maps to | Notes |
|
|
7
|
+
|---|---|---|---|
|
|
8
|
+
| `Enabled` | bool | none | Applies the contract. Default `false`. |
|
|
9
|
+
| `HostStore` | string | `Ante:HostStores` (one entry) | The application's own Chronicle store. Required unless development mode (then `Application`). |
|
|
10
|
+
| `EventStore`, `Namespace` | string | `Ante:EventStore`, `Ante:Namespace` | Optional. Ante's own store and fixed namespace. |
|
|
11
|
+
| `PublicBaseUrl` | absolute URL | `Ante:Invitations:Token:PublicBaseUrl` | Where users reach this Ante. HTTPS, or HTTP on loopback. |
|
|
12
|
+
| `ApplicationUrl` | URL | `Ante:HostAppUrl` | Where people go when onboarding completes. |
|
|
13
|
+
| `SignUp` | `CreateTenant` or `JoinTenant` | `Ante:Registration:Enabled` | `JoinTenant` closes `/register`. |
|
|
14
|
+
| `RegistrationEnabled` | bool, default `true` | `Ante:Registration:Enabled` | Always off when `SignUp` is `JoinTenant`. |
|
|
15
|
+
| `InvitationTypes` | list | none (runtime check) | `JoinTenant`, `CreateTenant`; unset allows both. |
|
|
16
|
+
| `Personas` | list | none (runtime check) | Grantable personas; ordinal comparison; unset or empty accepts any role. |
|
|
17
|
+
| `DefaultLocale`, `AllowedLocales` | string, list | `Ante:DefaultLocale`, `Ante:SupportedLocales` | |
|
|
18
|
+
| `Legal:Folder`, `Legal:TermsAndConditions`, `Legal:PrivacyPolicy` | paths | `Ante:Legal:Source=Files`, `Ante:Legal:Files:*` | Omit `Legal` for no legal step. |
|
|
19
|
+
| `Secrets:Path` | folder | any key | One file per setting, named like the key with `__` for `:`; trailing newline removed; names starting `.` skipped. |
|
|
20
|
+
| `Secrets:SigningKeyFile` | file path | `Ante:Invitations:Token:PrivateKeyPem` | PEM RSA private key, at least 2048 bits. |
|
|
21
|
+
| `Secrets:VerificationKeyFile` | file path | `Ante:Invitations:Token:PublicKeyPem` | Optional extra trusted public key. |
|
|
22
|
+
| `Development:Enabled`, `Development:DataPath` | bool, folder | none | Local runs only; see `SKILL.md`. |
|
|
23
|
+
|
|
24
|
+
The same instance still needs `Cratis:Chronicle:ConnectionString` and `Cratis:MongoDB`, normally
|
|
25
|
+
supplied by the Cratis environment. Attested-exchange settings, `Issuer`, `Audience` and `Expiry`
|
|
26
|
+
stay under `Ante:Invitations`.
|
|
27
|
+
|
|
28
|
+
Legal terms from files: the version is `sha256-` plus the first 16 hex characters of a SHA-256
|
|
29
|
+
over both bodies. The set is read on every request, so a changed mounted file applies without a
|
|
30
|
+
restart. Acceptance is recorded and published as `LegalTermsAccepted` carrying that version; Ante
|
|
31
|
+
does not publish `LegalDocumentSetActivated` for a file set.
|
|
@@ -0,0 +1,86 @@
|
|
|
1
|
+
# Performance resource
|
|
2
|
+
|
|
3
|
+
```yaml
|
|
4
|
+
apiVersion: showrunner.cratis.io/v1alpha1
|
|
5
|
+
kind: Performance
|
|
6
|
+
metadata:
|
|
7
|
+
name: crm
|
|
8
|
+
namespace: apps
|
|
9
|
+
spec:
|
|
10
|
+
productionRef:
|
|
11
|
+
name: ledger
|
|
12
|
+
chronicle:
|
|
13
|
+
connectionSecretRef:
|
|
14
|
+
name: chronicle-connection
|
|
15
|
+
application:
|
|
16
|
+
image: registry.example.com/crm:1.0.0
|
|
17
|
+
eventStores: [Crm]
|
|
18
|
+
environment:
|
|
19
|
+
name: production
|
|
20
|
+
configMapRef:
|
|
21
|
+
name: crm-environment
|
|
22
|
+
passphraseSecretRef:
|
|
23
|
+
name: crm-passphrase
|
|
24
|
+
authProxy:
|
|
25
|
+
enabled: true
|
|
26
|
+
providers:
|
|
27
|
+
- kind: EntraId
|
|
28
|
+
identity: EntraId
|
|
29
|
+
onboarding:
|
|
30
|
+
enabled: true
|
|
31
|
+
signUp: CreateTenant
|
|
32
|
+
personas: [Administrator, Member]
|
|
33
|
+
legal:
|
|
34
|
+
configMapRef:
|
|
35
|
+
name: crm-legal
|
|
36
|
+
ingress:
|
|
37
|
+
enabled: true
|
|
38
|
+
className: nginx
|
|
39
|
+
hosts: [crm.example.com]
|
|
40
|
+
tlsIssuer:
|
|
41
|
+
name: letsencrypt
|
|
42
|
+
```
|
|
43
|
+
|
|
44
|
+
## Fields that decide behavior
|
|
45
|
+
|
|
46
|
+
- Chronicle: `chronicle.connectionSecretRef` (an existing Secret) takes precedence over `productionRef`. The Secret is mounted as a file, never copied. `application.eventStores[0]` is the store Ante observes.
|
|
47
|
+
- `environment.configMapRef` holds `<name>.yaml` unless `key` says otherwise. `passphraseSecretRef` is only for a passphrase environment. Azure Key Vault uses the operator's workload identity; HashiCorp Vault uses Kubernetes auth with the operator's service account and `VAULT_K8S_ROLE`; both are chart values.
|
|
48
|
+
- `authProxy.providers` carry kind and identity only, matching the model. `onboarding` carries `signUp`, `personas` and legal files; every value comes from the environment.
|
|
49
|
+
- `onboarding.attestedProviders` set: Ante runs attested invitation exchange against AuthProxy's attestations; unset keeps the legacy exchange.
|
|
50
|
+
|
|
51
|
+
## Created resources (for a Performance named `crm`)
|
|
52
|
+
|
|
53
|
+
| Resource | Name | Notes |
|
|
54
|
+
|---|---|---|
|
|
55
|
+
| Deployment and Service | `crm-app`, `crm-authproxy` (when enabled), `crm-ante` (when onboarding) | ClusterIP; Ante has one replica. |
|
|
56
|
+
| Ingress | `crm` | Every host routes to AuthProxy only; certificate from cert-manager. |
|
|
57
|
+
| Secrets | `crm-app-environment`, `crm-authproxy-environment`, `crm-ante-secrets`, `crm-signing-keys` | Mounted content and generated keys. |
|
|
58
|
+
|
|
59
|
+
AuthProxy gets one file per environment key it needs in `/run/secrets/cratis`; Ante gets one file
|
|
60
|
+
per setting (`__` for `:`) in `/run/secrets/ante`; the application gets the remaining keys in
|
|
61
|
+
`/run/secrets/cratis`. Pods roll when mounted content changes, via a keyed hash annotation that
|
|
62
|
+
reveals nothing about a value. Ante's own MongoDB server comes from the environment key `ante.mongodb.server`.
|
|
63
|
+
|
|
64
|
+
## Status
|
|
65
|
+
|
|
66
|
+
| Field | Meaning |
|
|
67
|
+
|---|---|
|
|
68
|
+
| `phase` | `Pending`, `Blocked`, `Progressing` or `Ready`. |
|
|
69
|
+
| `publicUrl` | `https://` and the first ingress host. |
|
|
70
|
+
| `missingEnvironmentKeys` | Keys the environment lacks while `Blocked`. |
|
|
71
|
+
| `conditions` | `SpecValid`, `ChronicleConnection`, `EnvironmentResolved`, `EnvironmentComplete`, and per component `ApplicationReady`, `AuthProxyReady`, `AnteReady`. |
|
|
72
|
+
| `signingKeys` | Key ids in use, rotation counter applied, previous public keys pinned. |
|
|
73
|
+
|
|
74
|
+
Conditions and status never contain a secret value. An unresolved environment is reported in
|
|
75
|
+
`EnvironmentResolved` with a message naming the key and the provider.
|
|
76
|
+
|
|
77
|
+
## Signing keys
|
|
78
|
+
|
|
79
|
+
The operator generates the key Ante signs invitations with and the key AuthProxy signs
|
|
80
|
+
attestations with, in `crm-signing-keys`. Raise `spec.signingKeys.rotation` to rotate both. The
|
|
81
|
+
public half of each replaced key stays pinned (`signingKeys.retainPrevious`, two by default), so
|
|
82
|
+
Ante verifies invitations signed with a previous key.
|
|
83
|
+
|
|
84
|
+
Routing `/_invite` and `/.well-known/ante` from AuthProxy to Ante is configured on AuthProxy's
|
|
85
|
+
side; set `onboarding.lobbyBackendBaseUrl` in the environment when needed. Other Stage Manager
|
|
86
|
+
resources (`Production`, `Understudy`, `Restore`, `Rehearsal`, `BackstagePass`, `ControlRoom`) are schema only; nothing acts on them.
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
Copyright (c) Cratis. All rights reserved.
|
|
2
|
+
Licensed under the MIT license. See LICENSE file in the canonical Cratis/AI repository for the full license text.
|
|
3
|
+
|
|
4
|
+
Third-party notices
|
|
5
|
+
|
|
6
|
+
This skill adapts material from agentic-engineer by Martin Dilger and Nebulit GmbH
|
|
7
|
+
(https://github.com/Nebulit-GmbH/agentic-engineer, commit 07b0f30648d663cb588d7e2c7aa031af9dfc21f2;
|
|
8
|
+
https://nebulit.de), used with the explicit consent of Martin Dilger and Nebulit GmbH. The adapted
|
|
9
|
+
material remains credited to Martin Dilger and Nebulit GmbH.
|