@appshell/cli 1.0.0-alpha.106 → 1.0.0-alpha.108

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.
Files changed (3) hide show
  1. package/README.md +92 -26
  2. package/dist/main.js +5 -5
  3. package/package.json +2 -2
package/README.md CHANGED
@@ -50,20 +50,21 @@ Commands:
50
50
  appshell logout Discard the stored credential for a registry
51
51
  appshell publish Publish a package to the appshell registry
52
52
  appshell unpublish <name> <version> Remove a published package version
53
- appshell trust Trust CI workflows to publish into a scope
54
- without a stored secret
53
+ appshell trust Trust CI workflows to publish into a scope, or
54
+ workloads to apply its applications, without a
55
+ stored secret
55
56
  appshell outdated Analyzes shared dependencies for outdated versions
56
57
  ```
57
58
 
58
59
  These global options apply to every command:
59
60
 
60
- | Option | Default | Purpose |
61
- | ------ | ------- | ------- |
62
- | `-r, --registry` | `http://localhost:7070` | Registry to operate against |
63
- | `-a, --application` | — | Application, as `name` or `scope/name` |
64
- | `--scopeId` | `default` | Scope owning unqualified packages and applications |
65
- | `-k, --apiKey` | `""` | Api key, when the registry expects one |
66
- | `-v, --verbose` | `false` | Verbose output |
61
+ | Option | Default | Purpose |
62
+ | ------------------- | ----------------------- | -------------------------------------------------- |
63
+ | `-r, --registry` | `http://localhost:7070` | Registry to operate against |
64
+ | `-a, --application` | — | Application, as `name` or `scope/name` |
65
+ | `--scopeId` | `default` | Scope owning unqualified packages and applications |
66
+ | `-k, --apiKey` | `""` | Api key, when the registry expects one |
67
+ | `-v, --verbose` | `false` | Verbose output |
67
68
 
68
69
  `--registry` and `--application` fall back to `APPSHELL_REGISTRY` /
69
70
  `APPSHELL_APPLICATION`, then to `~/.appshell/config`. Set them once instead of
@@ -77,12 +78,12 @@ appshell config list
77
78
 
78
79
  ## Vocabulary
79
80
 
80
- | Term | Identity | What it is |
81
- | ---- | -------- | ---------- |
82
- | **Scope** | `acme` | Namespace and permission boundary |
83
- | **Package** | `acme/checkout@1.5.0` | What you publish. Immutable, digest-addressed |
84
- | **Application** | `acme/storefront` | The composition the registry serves |
85
- | **Remote** | `PingModule/Ping` | What the browser loads, over Module Federation |
81
+ | Term | Identity | What it is |
82
+ | --------------- | --------------------- | ---------------------------------------------- |
83
+ | **Scope** | `acme` | Namespace and permission boundary |
84
+ | **Package** | `acme/checkout@1.5.0` | What you publish. Immutable, digest-addressed |
85
+ | **Application** | `acme/storefront` | The composition the registry serves |
86
+ | **Remote** | `PingModule/Ping` | What the browser loads, over Module Federation |
86
87
 
87
88
  ## Authenticating
88
89
 
@@ -107,13 +108,13 @@ Publishing is idempotent: the same content under the same version is a no-op.
107
108
  Different content under an existing version is rejected unless the registry allows
108
109
  forcing. When `--application` resolves, publish also **activates** the version there.
109
110
 
110
- | Option | When omitted | Purpose |
111
- | ------ | ------------ | ------- |
112
- | `-t, --template` | `appshell.template.json` | Template to process |
113
- | `--name` | the unscoped `package.json` name | Package name |
114
- | `--package-version` | the `package.json` version | Version to publish as |
115
- | `--visibility` | the registry defaults to `private` | Whether other scopes may activate it |
116
- | `-w, --watch` | `false` | Republish whenever the template changes |
111
+ | Option | When omitted | Purpose |
112
+ | ------------------- | ---------------------------------- | --------------------------------------- |
113
+ | `-t, --template` | `appshell.template.json` | Template to process |
114
+ | `--name` | the unscoped `package.json` name | Package name |
115
+ | `--package-version` | the `package.json` version | Version to publish as |
116
+ | `--visibility` | the registry defaults to `private` | Whether other scopes may activate it |
117
+ | `-w, --watch` | `false` | Republish whenever the template changes |
117
118
 
118
119
  ```bash
119
120
  appshell unpublish checkout 1.5.0
@@ -203,6 +204,71 @@ locally where the webpack plugin already publishes and activates on every build.
203
204
  `${VAR}` placeholders expand from the environment exactly as they do in
204
205
  `appshell.config.yaml`.
205
206
 
207
+ ## Trusted deployment
208
+
209
+ A workload can apply an application with its own OIDC identity, so the job or controller
210
+ that keeps it at its declared state holds no secret either: a GitHub Actions workflow, or
211
+ a Kubernetes service account. The application's scope owner, or an organization admin,
212
+ records which workload may — the application must exist first:
213
+
214
+ ```bash
215
+ # A GitHub Actions workflow, by repository ids as for publishing
216
+ appshell trust add acme --application storefront \
217
+ --github acme/deploy --workflow deploy.yml --environment production
218
+
219
+ # A Kubernetes service account, under its cluster's OIDC issuer
220
+ appshell trust add acme --application storefront \
221
+ --kubernetes https://oidc.eks.us-east-1.amazonaws.com/id/EXAMPLE \
222
+ --namespace appshell --service-account deployer
223
+
224
+ appshell trust list acme --application storefront
225
+ appshell trust remove acme 1b2c3d4e --application storefront
226
+ ```
227
+
228
+ The cluster issuer is taken exactly as given and must be what the cluster's service
229
+ account tokens carry (`kubectl get --raw /.well-known/openid-configuration` prints it). The
230
+ registry fetches its keys from there, so the issuer's discovery document must be public:
231
+ EKS, GKE and AKS serve one, and a self-managed cluster needs its own published.
232
+
233
+ **From GitHub Actions**, with `id-token: write` and no `APPSHELL_TOKEN` or stored login,
234
+ `appshell app apply` asks the runner for a token for the registry's deploy audience — the
235
+ registry url with `/deploy`, or `APPSHELL_DEPLOY_AUDIENCE` when the registry's operator set
236
+ `TRUSTED_DEPLOYMENT_AUDIENCE` to something else — and applies with it:
237
+
238
+ ```yaml
239
+ permissions: { id-token: write, contents: read }
240
+ jobs:
241
+ deploy:
242
+ runs-on: ubuntu-latest
243
+ environment: production
244
+ steps:
245
+ - uses: actions/checkout@v4
246
+ - run: npx appshell app apply -f appshell.app.yaml --registry https://registry.appshell.org
247
+ ```
248
+
249
+ **From Kubernetes**, project a token for that audience and present it:
250
+
251
+ ```yaml
252
+ volumes:
253
+ - name: appshell-token
254
+ projected:
255
+ sources:
256
+ - serviceAccountToken:
257
+ audience: https://registry.appshell.org/deploy
258
+ expirationSeconds: 3600 # at most an hour is accepted
259
+ path: token
260
+ ```
261
+
262
+ ```bash
263
+ APPSHELL_TOKEN=$(cat /var/run/appshell/token) appshell app apply -f appshell.app.yaml
264
+ ```
265
+
266
+ A workload may only apply, only an application that already exists, and only one named as
267
+ `scope/name` in the resource, since it has no scope of its own. A refusal says what to
268
+ check: `appshell trust list <scope> --application <name>` against the job or account, or
269
+ the audience setting. Against a registry without trusted deployment enabled
270
+ (`AUTH_MODE=none`, every local one), apply retries once without a token.
271
+
206
272
  ## Inspecting an application
207
273
 
208
274
  ```bash
@@ -263,11 +329,11 @@ run it directly when you want the manifest as a build artifact.
263
329
  appshell generate manifest --template dist/appshell.template.json
264
330
  ```
265
331
 
266
- | Option | Default | Purpose |
267
- | ------ | ------- | ------- |
332
+ | Option | Default | Purpose |
333
+ | ---------------- | ------------------------ | ------------------- |
268
334
  | `-t, --template` | `appshell.template.json` | Template to process |
269
- | `-o, --outDir` | `dist` | Output location |
270
- | `-f, --outFile` | `appshell.manifest.json` | Output filename |
335
+ | `-o, --outDir` | `dist` | Output location |
336
+ | `-f, --outFile` | `appshell.manifest.json` | Output filename |
271
337
 
272
338
  **Where does the template come from?**
273
339