feat/v0-3-dashboard-role-enforcement #293
Open
johnride
wants to merge 2 commits from
feat/v0-3-dashboard-role-enforcement into feat/smoke-test-contract
pull from: feat/v0-3-dashboard-role-enforcement
merge into: NationTech:feat/smoke-test-contract
NationTech:master
NationTech:feat/fleet-ch2-operator-recovery
NationTech:feat/fleet-device-exec-logs
NationTech:feat/zitadel-web-pkce-and-human-user
NationTech:feat/jwt-bearer-openbao-auth
NationTech:feat/fleet-ch5-graceful-deploy-upgrade
NationTech:feat/fleet-ch4-agent-upgrade
NationTech:feat/fleet-ch3-log-streaming
NationTech:feat/add-claims-for-openbao
NationTech:refactor/move-zitadel-jwt-to-module
NationTech:feat/fleet-operator-real-data
NationTech:docs/fleet-secrets-device-access
NationTech:chore/fleet-operator-prune-mock-dtos
NationTech:chore/rename-release-to-publish
NationTech:refactor/config-namespace-env-var
NationTech:feat/fleet-staging-openbao
NationTech:feat/auth-add-next-url-redirect
NationTech:pr/harmony-sso-example
NationTech:feat/unified-config-and-secrets
NationTech:ci/fleet-argo-cd
NationTech:ci/fleet-operator-release-pipeline
NationTech:feat/on-device-key-gen
NationTech:feat/install-gitea
NationTech:feat/v0-3-logs-companion
NationTech:refactor/smoke-companion-minimal
NationTech:feat/smoke-test-contract
NationTech:feat/iobench-redpanda-profile
NationTech:feat/v0-3-init-containers
NationTech:feat/v0-3-operator-restart-baseline
NationTech:feat/fleet-e2e-x86
NationTech:feat/ceph-score
NationTech:feat/opnsense-bootstrap-score
NationTech:feat/fleet-e2e
NationTech:feat/fleet-e2e-harness-and-ping
NationTech:feat/dashboard-auth
NationTech:feat/fleet-operator-web-frontend
NationTech:feat/deploy_fleet_server_side
NationTech:feat/openwebui
NationTech:feat/iot-aggregation-scale
NationTech:feat/iot-operator-helm-chart
NationTech:feat/removesideeffect
NationTech:feat/test-alert-receivers-sttest
NationTech:feat/brocade-client-add-vlans
NationTech:feat/agent-desired-state
NationTech:feat/opnsense-dns-implementation
NationTech:feat/named-config-instances
NationTech:worktree-bridge-cse_012j1jB37XfjXvDGHUjHrKSj
NationTech:chore/leftover-adr
NationTech:feat/config_e2e_zitadel_openbao
NationTech:example/vllm
NationTech:feat/config_sqlite
NationTech:chore/roadmap
NationTech:feature/kvm-module
NationTech:feat/rustfs
NationTech:feat/harmony_assets
NationTech:feat/brocade_assisted_setup
NationTech:feat/cluster_alerting_score
NationTech:e2e-tests-multicluster
NationTech:fix/refactor_alert_receivers
NationTech:feat/change-node-readiness-strategy
NationTech:feat/zitadel
NationTech:feat/improve-inventory-discovery
NationTech:fix/monitoring_abstractions_openshift
NationTech:feat/nats-jetstream
NationTech:adr-nats-creds
NationTech:feat/st_test
NationTech:feat/dockerAutoinstall
NationTech:chore/cleanup_hacluster
NationTech:doc/cert-management
NationTech:feat/certificate_management
NationTech:adr/017-staleness-failover
NationTech:fix/nats_non_root
NationTech:feat/rebuild_inventory
NationTech:fix/opnsense_update
NationTech:feat/unshedulable_control_planes
NationTech:feat/worker_okd_install
NationTech:doc-and-braindump
NationTech:fix/pxe_install
NationTech:switch-client
NationTech:okd_enable_user_workload_monitoring
NationTech:configure-switch
NationTech:fix/clippy
NationTech:feat/gen-ca-cert
NationTech:feat/okd_default_ingress_class
NationTech:fix/add_routes_to_domain
NationTech:secrets-prompt-editor
NationTech:feat/multisiteApplication
NationTech:feat/ceph-install-score
NationTech:feat/ceph-osd-score
NationTech:feat/ceph_validate_health
NationTech:better-indicatif-progress-grouped
NationTech:feat/crd-alertmanager-configs
NationTech:better-cli
NationTech:opnsense_upgrade
NationTech:feat/monitoring-application-feature
NationTech:dev/postgres
NationTech:feat/cd/localdeploymentdemo
NationTech:feat/webhook_receiver
NationTech:feat/kube-prometheus
NationTech:feat/init_k8s_tenant
NationTech:feat/discord-webhook-receiver
NationTech:feat/kube-prometheus-monitor
NationTech:feat/tenantScore
NationTech:feat/teams-integration
NationTech:feat/slack-notifs
NationTech:monitoring
NationTech:runtime-profiles
Reference in New Issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.
No description provided.
Delete Branch "feat/v0-3-dashboard-role-enforcement"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
Removes the brittle pieces that landed in the original role-enforcement commit: `extract_roles(value, path)` walking `serde_json::Value` with a `path.contains("urn:")`-aware splitter, an env-driven `FLEET_AUTH_ROLES_CLAIM`, and `VerifiedSession.roles: Vec<String>` compared with `iter().any(|r| r == "fleet-admin")` in middleware. This is a security-relevant code path; runtime string heuristics inside it hide injection-shaped bugs (a misconfigured env or a custom Zitadel mapper shifts the lookup to a path the attacker controls). Replaced with end-to-end typed serde decoding: * `Role` — closed enum (one variant today: `FleetAdmin`). Adding a variant is a deliberate code change to the security path. Unknown role names emitted by the IdP cannot be represented and therefore cannot grant access. * `RoleClaims` — wire-side struct, flattened into the JWT `Claims`. The two well-known role-claim locations are matched verbatim by `#[serde(rename = "urn:zitadel:iam:org:project:roles")]` and `#[serde(rename = "roles")]`. No dotted-path navigation. No env string. If a future issuer adds a third location it is an additive `#[serde(rename = ...)]` field inside the security boundary. * `Roles` — domain value on `VerifiedSession`. Construction is restricted to `RoleClaims::into_roles` plus a typed `FromIterator<Role>` for test fixtures. `Roles::has(Role::FleetAdmin)` is the only check the middleware needs; no string comparison exists anywhere downstream. * Malformed shapes (scalar at the URN path, mixed-type array) now ERROR at decode rather than degrading to an empty-vec "closed door". Fail-loud is the security-correct default when the IdP misbehaves — the user re-logs in, the operator notices. Callout side: reverted the shared-extract_roles delegation. The callout retains its own, unchanged role-extraction logic. We do NOT need cross-crate sharing here, and the shared extractor was the entry point we were trying to delete — the callout's own behaviour was the status quo and is preserved verbatim. Dropped exports: `DEFAULT_ADMIN_ROLE`, `DEFAULT_ROLES_CLAIM`, `extract_roles`, `ROLES_CLAIM_ENV`, `ZitadelAuthConfig.roles_claim`. None had external consumers in the workspace. Tests: * 12 tests on `RoleClaims` deserialization: both shapes resolve, Zitadel URN wins precedence, unknown roles dropped, malformed scalar/mixed-type arrays error at decode, missing claim → empty, empty object/array → empty, extra unrelated claims are ignored, display matches wire spelling. * 4 middleware tests on the typed `require_role(Role::FleetAdmin, …)` path. Dropped the redundant "admin-only vs admin+other" test — with a single-variant enum it duplicated the positive case.The current callout get the role claim location and role names from env variable but the new dashboard code has them hardcoded. Is that intentional? If deployments can customize those values dashboard auth and NATS auth can disagree if I'm not mistaken
View command line instructions
Checkout
From your project repository, check out a new branch and test the changes.