Skip to content

Phase 2: grants, node attributes, and policy settings UX#15

Open
CJFWeatherhead wants to merge 2 commits into
mainfrom
feat/policy-model-modernisation
Open

Phase 2: grants, node attributes, and policy settings UX#15
CJFWeatherhead wants to merge 2 commits into
mainfrom
feat/policy-model-modernisation

Conversation

@CJFWeatherhead

@CJFWeatherhead CJFWeatherhead commented Jul 3, 2026

Copy link
Copy Markdown
Member

Summary

Implements Phase 2 from docs/headscale-0.29.x-agentic-workplan.md with scope tightly focused on:

  • Grants UX (src, dst, ip, via, srcPosture, app)
  • Node Attributes UX (target, attr)
  • Top-level policy setting randomizeClientPort
  • Deterministic e2e coverage for create/edit/delete and persistence

This iteration also replaces the grants capability JSON textarea with a form builder.


What changed

1) New policy tabs and editors

  • Added tabs in src/routes/acls/+page.svelte:
    • Grants
    • Node Attributes
    • Policy Settings
  • Added components:
    • src/routes/acls/Grants.svelte
    • src/routes/acls/NodeAttrs.svelte
    • src/routes/acls/PolicySettings.svelte

2) Grants editor (form builder)

In src/routes/acls/Grants.svelte:

  • Added editable sections for:
    • src (selector chips/autocomplete)
    • dst (selector chips/autocomplete)
    • ip (CIDR/IP chips)
    • srcPosture (chips)
    • via (tag-only selectors + validation hint)
  • Added Taildrive preset button:
    • capability key tailscale.com/cap/drive
    • entries for shares and access
  • Replaced freeform app JSON block with a row-based capability form builder:
    • add/remove capability rows
    • per-row capability key input
    • per-row JSON-array value textarea
    • validation on apply (JSON parse, array requirement, duplicate key detection)

3) Node Attributes editor

In src/routes/acls/NodeAttrs.svelte:

  • Added CRUD-friendly UI for nodeAttrs
  • Added target selector UI with existing users/groups/tags/hosts options
  • Added Taildrive attribute presets:
    • drive:share
    • drive:access

4) Policy settings

In src/routes/acls/PolicySettings.svelte:

  • Added toggle for top-level randomizeClientPort

5) E2E and mock enhancements

  • Added e2e/policy-phase2.spec.ts:
    • create + persist grants/nodeAttrs/randomizeClientPort
    • delete + persist grant changes
  • Updated e2e/mock-api.mjs to persist policy updates in-memory for deterministic round-trip assertions

Why this approach

  • Keeps Phase 2 strictly scoped (no Phase 3 auth/SSH changes).
  • Preserves the existing non-destructive policy pipeline while making modern fields practical to edit.
  • Form-builder UX for grant capabilities reduces operator error compared with single-block JSON editing.

Test evidence (containerised)

Executed with Docker-based workflows:

  • svelte-check ✅ pass
  • vitest ✅ pass (55/55)
  • vite build ✅ pass
  • Static route checks (build/index.html, build/settings/index.html, build/nodes/index.html, build/users/index.html, build/200.html) ✅ pass
  • Docker route smoke checks (/admin/, /admin/nodes/, /admin/settings/, /admin/users/, /admin/nonexistent/) ✅ pass
  • e2e/policy-phase2.spec.ts ✅ pass (2/2)

Note: a full suite run previously showed one unrelated flaky failure in preauth deletion e2e, outside this change scope.


Non-goals

  • SSH check mode enhancements (action: check, checkPeriod, acceptEnv) — Phase 3
  • Auth approve/reject/register workflows — Phase 3
  • Broad docs hardening/release notes work — Phase 4

Risks / limitations

  • Capability form values are still JSON-array text per row (validated on apply), not fully schema-driven field widgets.
  • via enforcement is a client-side guardrail; server remains the source of truth.

Follow-up recommendations

  1. Introduce schema-aware editors for common capability payloads (starting with Taildrive).
  2. Add reusable selector validation helpers shared across grants/nodeAttrs/SSH editors.
  3. Stabilise flaky preauth delete e2e independently to improve full-suite CI signal.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant