You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
deploy/scripts/new-env.mjs accepts CLI flags for infra/edge/TLS knobs
(--subscription, --location, --edge-mode, --tls-source, --acme-email, --foundry-enabled) but not for portal auth
(PORTAL_AUTH_* / PORTAL_AUTHZ_*). Operators must scaffold first,
then edit the rendered .env by hand.
This creates two real failure modes:
No early validation. Invariants like PROVIDER=entra ⇒ ENTRA_TENANT_ID and ENTRA_CLIENT_ID must both be set are not
caught at scaffold time. Bad config surfaces at the
portal-manifests step, often after several minutes of Bicep.
Sentinel-vs-empty trap. Operator clears __PS_UNSET__ to an
empty string to express "I don't want this key set" — but substitute-env.mjs rejects empty values for portal config keys,
only the literal sentinel passes. The portal-manifests step fails
with Unresolved overlay .env keys: PORTAL_AUTHZ_ADMIN_GROUPS, ....
Hit this during chkentra2 validation of PR Portal authz: deny-by-default; -AssignmentRequired is advanced opt-in #37; documented in .github/skills/pilotswarm-new-env-deploy/SKILL.md Step 3a but
first-class flag validation would prevent the trap entirely.
Proposal
Add to new-env.mjsINPUTS:
--portal-auth-provider (none|entra)
--portal-auth-entra-tenant-id
--portal-auth-entra-client-id
--portal-auth-allow-unauthenticated (true|false)
--portal-authz-default-role (none|user|admin)
--portal-auth-entra-admin-groups
--portal-auth-entra-user-groups
--portal-authz-admin-groups
--portal-authz-user-groups
Cross-validate at scaffold time:
provider=entra ⇒ tenant-id and client-id both required
default-role must be in {none, user, admin}
Empty flag value (e.g. --portal-authz-admin-groups=) auto-rewrites
to __PS_UNSET__ in the rendered .env, eliminating the trap.
recommend flag-driven scaffold over scaffold-then-edit
deploy/scripts/README.md — flag reference table
Acceptance
Fresh stamp can be scaffolded fully non-interactively with no
post-scaffold .env editing required.
new-env mystamp --portal-auth-provider=entra without --portal-auth-entra-tenant-id fails fast with a clear error.
Empty-string portal auth flag values render as __PS_UNSET__ in
the rendered .env.
Context
Filed after deploying PR #37 (feature/default-assignment-required-false)
to a fresh chkentra2 stamp. PR #37 validated successfully end-to-end
(admin sign-in works, appRoleAssignmentRequired=false,
deny-by-default engine), but the deploy hit the sentinel-vs-empty trap
because I (Copilot CLI) cleared sentinels to empty strings when
hand-editing the scaffolded .env. This issue is the structural fix.
Problem
deploy/scripts/new-env.mjsaccepts CLI flags for infra/edge/TLS knobs(
--subscription,--location,--edge-mode,--tls-source,--acme-email,--foundry-enabled) but not for portal auth(
PORTAL_AUTH_*/PORTAL_AUTHZ_*). Operators must scaffold first,then
editthe rendered.envby hand.This creates two real failure modes:
No early validation. Invariants like
PROVIDER=entra⇒ENTRA_TENANT_IDandENTRA_CLIENT_IDmust both be set are notcaught at scaffold time. Bad config surfaces at the
portal-manifests step, often after several minutes of Bicep.
Sentinel-vs-empty trap. Operator clears
__PS_UNSET__to anempty string to express "I don't want this key set" — but
substitute-env.mjsrejects empty values for portal config keys,only the literal sentinel passes. The portal-manifests step fails
with
Unresolved overlay .env keys: PORTAL_AUTHZ_ADMIN_GROUPS, ....Hit this during chkentra2 validation of PR Portal authz: deny-by-default; -AssignmentRequired is advanced opt-in #37; documented in
.github/skills/pilotswarm-new-env-deploy/SKILL.mdStep 3a butfirst-class flag validation would prevent the trap entirely.
Proposal
Add to
new-env.mjsINPUTS:--portal-auth-provider(none|entra)--portal-auth-entra-tenant-id--portal-auth-entra-client-id--portal-auth-allow-unauthenticated(true|false)--portal-authz-default-role(none|user|admin)--portal-auth-entra-admin-groups--portal-auth-entra-user-groups--portal-authz-admin-groups--portal-authz-user-groupsCross-validate at scaffold time:
provider=entra⇒tenant-idandclient-idboth requireddefault-rolemust be in{none, user, admin}--portal-authz-admin-groups=) auto-rewritesto
__PS_UNSET__in the rendered.env, eliminating the trap.Scope
deploy/scripts/new-env.mjs— INPUTS additions + cross-validationdeploy/scripts/test/new-env.test.mjs(or equivalent) — flagsurface + invariant tests
.github/skills/pilotswarm-new-env-deploy/SKILL.md— Step 2 tabledeploy/scripts/README.md— flag reference tableAcceptance
post-scaffold
.envediting required.new-env mystamp --portal-auth-provider=entrawithout--portal-auth-entra-tenant-idfails fast with a clear error.__PS_UNSET__inthe rendered
.env.Context
Filed after deploying PR #37 (
feature/default-assignment-required-false)to a fresh
chkentra2stamp. PR #37 validated successfully end-to-end(admin sign-in works,
appRoleAssignmentRequired=false,deny-by-default engine), but the deploy hit the sentinel-vs-empty trap
because I (Copilot CLI) cleared sentinels to empty strings when
hand-editing the scaffolded
.env. This issue is the structural fix.