Commit Graph

42 Commits

Author SHA1 Message Date
Oliver Kieselbach ac31ee980e feat(ci): mirror agent artifacts to legacy storage (transition until download.-alias migration; fail-soft, counter stays on eu only) 2026-07-18 15:57:40 +02:00
Oliver Kieselbach 1bf352542d fix(ci): agent version MERGE targets the eu table endpoint
The AdminConfiguration table SAS is issued for autopilotmonitoreu; the
MERGE URL still pointed at the legacy account and failed auth.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 15:11:54 +02:00
Oliver Kieselbach e2d711dc30 Merge branch 'migration/net10' 2026-07-18 14:03:29 +02:00
Oliver Kieselbach dd39205486 feat(migration): pivot global resource names to eu suffix
Cross-tenant re-claim of recently deleted global names is denied by
Azure by design (dangling-DNS/subdomain-takeover protection). New
tenant resources therefore use eu-suffixed names; the old names live
on in the old subscription (storage 'autopilotmonitor' recreated as
legacy bootstrap-URL keepalive, FuncApp/ACR kept as tombstones).

- API base URL -> autopilotmonitor-api-eu.azurewebsites.net
  (Shared Constants, web CSP + /go fallback, MCP default)
- Agent blob container + build counter -> autopilotmonitoreu
- deploy-backend app-name, deploy-mcp ACR -> eu names
- Bootstrap script URLs stay on the legacy storage (customers
  migrate once to a domain alias later)

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-18 14:02:55 +02:00
Oliver Kieselbach 7377eb9e4d fix(ci): use current repo slug in attestation verify hints
gh attestation verify only passes with the repo's current name
(okieselbach/AutopilotMonitor); the signed workflow identity carries it,
and the old dashed name fails identity matching even though git-remote
redirects still work. Verified against the first attested dry-run ZIP.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 11:22:15 +02:00
Oliver Kieselbach b2b99e78b4 fix(ci): tolerate leading '?' in SAS token secrets
First real run of build-agent.yml failed the counter CAS write with
"AuthenticationFailed ... sp is mandatory": the AZURE_BLOB_AGENT_SAS_TOKEN
secret stores the query with its leading '?', and the workflow prepends
another one, so Azure saw '?sp' as the first parameter name. The pre-existing
upload step had the same latent bug -- it had just never run. Normalize with
TrimStart('?') at all three usage sites (counter, blob upload, table merge).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 11:00:10 +02:00
Oliver Kieselbach 6d7783566f feat(ci): shared build-counter blob, CI build parity, ZIP provenance attestation
Build numbers now come from a public counter blob (buildcounter-v2.txt,
reserve-before-build with ETag-CAS) shared by local build.ps1 and CI, so the
two paths can never mint the same number. The CI step that committed
buildcounter.txt bumps to main is gone; the repo file is now a gitignored
offline fallback for -SkipUpload smoke builds only.

CI parity fixes vs the local build:
- ship SummaryDialog.exe.config in the ZIP (WPF AppContextSwitchOverrides;
  without it the dialog dies with 0x8007045A when spawned from SYSTEM)
- verify EXE version == manifest == reserved build number before zipping
- update the AdminConfiguration hash-oracle only on publish_as_stable

CI-built release ZIPs now carry a GitHub Artifact Attestation (Sigstore
keyless provenance, actions/attest-build-provenance@v4).

Doc: docs/agent/build-counter-blob.md

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-17 10:49:18 +02:00
Oliver Kieselbach 7521158e65 backend: bump to .NET 10 (dotnet-isolated 10.0) for the Flex recreate
TargetFramework net8.0 -> net10.0 (Functions + Tests), setup-dotnet 8.0.x -> 10.0.x. JwtBearer 8.0.11 -> 10.0.10 (Microsoft.Identity.Web 4.3.0 requires >= 10.0.0 on net10). Drops the System.Formats.Asn1 / System.Security.Cryptography.Xml vuln-override pins - superseded by the net10 framework versions (NU1510). Build clean, 2937/2937 backend tests green. Merge on cutover Saturday BEFORE running deploy-backend (the new Flex app is created as dotnet-isolated 10.0).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 21:34:22 +02:00
Oliver Kieselbach f0a5e550d3 ci: switch Azure deploy login to secret-less OIDC (federated credential)
deploy-backend + deploy-mcp now authenticate via azure/login OIDC (client-id/tenant-id/subscription-id + id-token permission) instead of the AZURE_CREDENTIALS service-principal secret. Adds temporary oidc-login-test workflow to smoke-test the federated login. Federated credential 'github-main' (repo:okieselbach/Autopilot-Monitor:ref:refs/heads/main) created on the deploy app registration.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-14 17:47:25 +02:00
Oliver Kieselbach 6529d972cd ci: bump checkout to v5 in SWA workflow too (missed in cb67e8c2)
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:52:42 +02:00
Oliver Kieselbach cb67e8c2f0 ci: bump actions to node24-ready versions ahead of June 16 forced default
GitHub forces all JS actions onto Node 24 starting 2026-06-16 and
removes Node 20 from runners on 2026-09-16. Bump every affected action
to the first major that officially declares node24, avoiding majors
with functional changes (checkout v6, upload-artifact v7):

  actions/checkout            v4 -> v5
  azure/login                 v2 -> v3
  actions/setup-dotnet        v4 -> v5
  actions/setup-node          v4 -> v5
  actions/upload-artifact     v4 -> v6 (v5 still defaulted to node20)
  softprops/action-gh-release v2 -> v3
  stefanzweifel/git-auto-commit-action v5 -> v7 (v7 reverted the v6
    input removals; only standard inputs used here anyway)

Azure/functions-action@v1 (floating tag, node24 since v1.5.4) and
Azure/static-web-apps-deploy@v1 (Docker action) need no change.
All target tags verified to exist via git ls-remote.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-06-12 16:52:01 +02:00
Oliver Kieselbach d51bde6017 refactor(release): parametric per-line agent build pipeline
Replaces V1/V2-hardcoded build + bootstrap with a single parametric
pipeline that scales to V3+ without rewrites. Full architecture in
.claude/plans/v2-cutover.md.

Stable namespace (Bootstrap-side, never renamed): generic Bootstrap
script, agent owns its --install defaults so it works for any line.
Versioned namespace (per-line, SelfUpdater-side): isolated *-v{N}.*
blobs; SelfUpdater never crosses lines or touches stable.

Backend GetAgentConfig dispatches per X-Agent-Version-Major to
AdminConfiguration.GetAgentLine(int) -> LatestAgentV{N}* fields.
Future V3 = add field set + switch arm. TableConfigRepository.Map
falls back to legacy unsuffixed columns for transparent migration.

V1 SelfUpdater now reads version-v1.json (would have been clobbered
by the V2 cutover otherwise). V2 agent owns its own 600s TenantId-wait
default so the Bootstrap calls --install plain.

Tests: 3289 across 6 suites, all green.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-09 19:36:53 +02:00
Oliver Kieselbach 7abbd59333 revert: roll back .NET 10 upgrade — Flex stamp missing runtime
Reverts:
- 8dacce5c "chore(backend): bump optional NuGet patches + fix SYSLIB0057"
- 2f68fe69 "chore(backend): upgrade Functions from .NET 8 to .NET 10 isolated"

After deploy succeeded and the Flex Consumption stack was switched to
.NET 10 Isolated in the portal, the dotnet-isolated worker died on every
boot with: dotnet exited with code 150 (FrameworkMissingFailure) and
"Exceeded language worker restart retry count for runtime:dotnet-isolated".
The deployed package was correct (TFM net10.0, FrameworkReference 10.0.0,
all package bumps applied) and the runtime stack property was set to
dotnet-isolated 10.0, but the .NET 10 runtime is not present on the
Flex Consumption stamp in West Europe even though Microsoft lists
DOTNET-ISOLATED|10.0 as supported. Restart and stop+start did not help.

Recovery sequence:
1. Stack switched back to .NET 8 Isolated (manual portal action).
2. Re-deployed last known-good net8.0 commit 637bd9a1 via temp branch
   rollback-net8 (now safe to delete).
3. /api/health back to 200.

Follow-ups:
- Re-apply security fixes (DataProtection 10.0.7 pin GHSA-9mv3-2cwr-p262,
  SYSLIB0057 X509CertificateLoader migration) on net8.0 in a separate PR.
- Open Microsoft support: ".NET 10 Isolated worker on Flex Consumption
  WestEurope fails with FrameworkMissingFailure despite stack listed as
  supported."

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 07:42:56 +02:00
Oliver Kieselbach 2f68fe69c0 chore(backend): upgrade Functions from .NET 8 to .NET 10 isolated
- Target framework: net8.0 -> net10.0 (Functions + Tests)
- Microsoft.Identity.Web 4.3.0 -> 4.8.0 (transitively pulls AspNetCore 10.x)
- Microsoft.AspNetCore.Authentication.JwtBearer 8.0.11 -> 10.0.7
- Microsoft.Extensions.Http.Polly 8.0.25 -> 10.0.7
- Pin Microsoft.AspNetCore.DataProtection 10.0.7 to override transitive
  10.0.0 (GHSA-9mv3-2cwr-p262 critical, GHSA-37gx-xxp4-5rgx +
  GHSA-w3x6-4m5h-cxqf high in Cryptography.Xml)
- Add global.json pinning SDK 10.0.x latestFeature, allowPrerelease=false
- CI deploy-backend workflow: setup-dotnet 8.0.x -> 10.0.x ga

Tests: 781/781 passing on net10.0.

Runtime stack switch on the Function App ("Stack settings" in portal:
.NET 8 Isolated -> .NET 10 Isolated) must be done manually after deploy.

Out of scope (carry as follow-ups):
- SYSLIB0057 (X509Certificate2 ctor obsolete) in CertificateValidator.cs:69
- Optional bumps surfaced by 'list package --outdated':
  Azure.Identity 1.19->1.21, Azure.Storage.Blobs 12.22->12.27,
  Azure.Data.Tables 12.9->12.11, SignalR.Management 1.29->1.33,
  Newtonsoft.Json 13.0.3->13.0.4. Major bumps deferred:
  ApplicationInsights.WorkerService 2.x->3.x, Resend 0.2->0.5.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-29 07:08:28 +02:00
Oliver Kieselbach 42ff4284d8 added version info to backend 2026-04-22 19:36:19 +02:00
Oliver Kieselbach 09899a90ac ci(web): allow workflow_dispatch to run the deploy job
The build_and_deploy_job's if-guard accepted push + non-closed PR
events only, so manually triggering the Static Web Apps workflow via
`gh workflow run` ran but skipped both jobs (conclusion=skipped).
After the V2-refactor merge to main (commit 62c0c990), the automatic
push-triggered run did not materialise on the merge commit — likely
a path-filter + merge-commit edge case on GitHub's side — leaving
no way to ship the web changes without either another path-touching
push or hand-editing the workflow.

Adding `github.event_name == 'workflow_dispatch'` to the if-guard
keeps the close-PR job untouched while making manual runs a reliable
escape hatch for future merge-commit oddities.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-21 15:54:48 +02:00
Oliver Kieselbach e9fcb85797 feat: added LatestVersions api and bootstrapper version handling and hints (badge, docs) 2026-04-09 19:50:13 +02:00
Oliver Kieselbach 66d9795105 fix post-config integrity check: use separate EXE hash instead of ZIP hash
The post-config binary integrity check was comparing the running EXE's
SHA-256 against LatestAgentSha256 which is the hash of the ZIP package —
these can never match. Introduces LatestAgentExeSha256 as a separate hash
computed from AutopilotMonitor.Agent.exe at build time, flowing through
AdminConfiguration → AgentConfigResponse → MonitoringService.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-03 19:49:20 +02:00
Oliver Kieselbach 55b077659d bug fix bootstrap 2026-03-31 23:30:43 +02:00
Oliver Kieselbach 1a89080f0f agent docs updates 2026-03-31 21:25:51 +02:00
Oliver Kieselbach e7e23f8243 fix merge call 2026-03-29 22:59:20 +02:00
Oliver Kieselbach d1ffac14bc hardened integrity check of agent via SHA256 from version.json and agent config (download and runtime check) 2026-03-29 22:56:11 +02:00
Oliver Kieselbach 8a4a7cf255 Remote MCP server: Streamable HTTP transport, Container App deployment, MCP user access control
- MCP server: stdio → Streamable HTTP (Express) with /health endpoint
- Auth: device code flow → token pass-through (JWT from Claude Code client)
- Dockerfile (multi-stage, node:22-slim) + .dockerignore
- Bicep template: ACR + Container App Environment + Container App (scale-to-zero)
- GitHub Actions: deploy-mcp.yml workflow, all backend workflows migrated to SP auth
- Removed unused dev/main deploy workflows
- Backend: McpAccessPolicy enum (Disabled/WhitelistOnly/AllMembers)
- Backend: McpUsers table + McpUserService (5min cache) + McpUserFunction (CRUD + access check)
- Backend: 6 endpoints registered in EndpointAccessPolicyCatalog
- Web UI: MCP Users management section at /settings/access/mcp-users
- Web UI: user list, add/remove/enable/disable, policy info banner

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-28 08:09:58 +01:00
Claude 50cc268738 feat: add SummaryDialog build and Azure Blob Storage upload to agent workflow
- Build SummaryDialog (WPF) alongside Agent and bundle into same ZIP
- Upload AutopilotMonitor-Agent.zip + version.json to Azure Blob Storage
  (matches bootstrap script download URL pattern)
- Compute Content-MD5 header for ZIP integrity validation
- New workflow input to toggle blob upload independently from release

Requires AZURE_BLOB_AGENT_SAS_TOKEN secret for blob storage access.

https://claude.ai/code/session_01QiuThUkeSEbiapFpTY9yRp
2026-03-26 18:15:08 +00:00
Claude ddc0328922 feat: add GitHub Actions workflow for Agent build & release
On-demand workflow (workflow_dispatch) that:
- Builds the .NET Framework 4.8 Agent on Windows runner
- Auto-increments build counter or accepts manual override
- Creates a ZIP artifact with all build outputs + version.json
- Optionally creates a GitHub Release with the artifacts
- Commits updated buildcounter.txt back to the repo

https://claude.ai/code/session_01QiuThUkeSEbiapFpTY9yRp
2026-03-26 18:11:08 +00:00
Oliver Kieselbach ffc2f1f67f Remove submodules: true from web deploy workflows
The private submodule (.claude/commands) is not needed for builds
and was causing CI failures since the runner has no access to it.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-03-26 07:15:00 +01:00
Oliver Kieselbach 53a3768cdf added valid return codes 2026-03-20 08:21:04 +01:00
Oliver Kieselbach 39d888cfb1 SEO optimizations 2026-03-20 08:07:17 +01:00
Oliver Kieselbach 6f483863d5 updated workflows 2026-03-19 23:13:13 +01:00
Oliver Kieselbach 5e99c96821 added dev workfows 2026-03-17 18:00:07 +01:00
Oliver Kieselbach 91d46e5cde added backend workflow 2026-03-13 23:35:30 +01:00
Oliver Kieselbach 20c2b7a196 updated checkout action to v4 2026-03-11 22:07:02 +01:00
Oliver Kieselbach e5b0faf692 fixed combine workflow to allwow push 2026-02-28 14:10:39 +01:00
Oliver Kieselbach 1f796bf6e3 feat: externalize rules to GitHub + API consolidation + preview mode
## Rules as GitHub single source of truth
- Add 75 individual JSON rule files (2 gather, 18 analyze, 55 IME patterns)
  under rules/gather/, rules/analyze/, rules/ime-log-patterns/
- Add JSON Schemas for all three rule types with VS Code IntelliSense support
- Add CI combine script (rules/scripts/combine.js) + GitHub Action that
  validates schemas with ajv-cli and generates rules/dist/ combined files
- Convert BuiltIn*.cs from hardcoded C# objects to embedded JSON resource loaders
- Add GitHubRuleRepository service to fetch dist/ files from raw.githubusercontent.com
- Add ReseedFromGitHubFunction: POST /api/rules/reseed-from-github?type=all|gather|analyze|ime

## IME Log Patterns
- Extend ImeLogPattern model with Description and IsBuiltIn properties
- Add ImeLogPatterns table + API constants
- Add TableStorageService CRUD methods for IME log patterns
- Add ImeLogPatternService (CRUD, merge, auto-seed from embedded JSON)
- Add ImeLogPatternsFunction: GET/PUT /api/rules/ime-log-patterns (Phase 1: read-only
  for tenants, Galactic Admin can enable/disable/edit globally)
- Add IME Log Patterns management page (/ime-log-patterns)
- Wire GetAgentConfigFunction to use ImeLogPatternService instead of static class

## API route consolidation
- All rule endpoints now under /api/rules/* for single certificate exclusion path:
  /api/rules/gather, /api/rules/analyze, /api/rules/ime-log-patterns,
  /api/rules/reseed-from-github

## Export buttons
- Add per-rule and export-all JSON download buttons to gather-rules,
  analyze-rules, and ime-log-patterns pages

## Admin configuration
- Replace old individual reseed buttons with unified "Fetch & Reseed from GitHub"
  (calls new GitHub endpoint) plus compact individual-type reseed buttons
- Add CDN cache hint: GitHub raw.githubusercontent.com caches up to 5 minutes

## Preview mode
- ?preview=1 URL param seeds localStorage.previewMode (persists across navigation)
- ?preview=0 clears it; toggle in Navbar settings dropdown (indigo, eye icon)
- IME Log Patterns nav link gated behind galacticAdminMode OR previewMode
- Preview badge shown on nav link when active for normal users

## Tests
- Add xUnit test project (net8.0) with 5 tests for embedded resource loading,
  known IME actions validation, and valid categories check

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-28 13:12:09 +01:00
Oliver Kieselbach dc30e4c9dd fix missing next platform stats url var in workflow, and fix wording in admin config 2026-02-18 12:42:11 +01:00
Oliver Kieselbach 1f1b2cf2b4 usage of EntraId ClientId harmonised 2026-02-16 18:18:42 +01:00
Oliver Kieselbach 543b574014 changed workflow to prevent unnecessary builds 2026-02-13 12:46:19 +01:00
Oliver Kieselbach 7f1637e40f Update azure-static-web-apps-brave-grass-0070b5703.yml
allow manual trigger
2026-02-10 22:49:54 +01:00
Oliver Kieselbach f09e9d1252 Update azure-static-web-apps-brave-grass-0070b5703.yml
move to vars
2026-02-10 22:39:53 +01:00
Oliver Kieselbach 8520287305 Update azure-static-web-apps-brave-grass-0070b5703.yml
added next urls
2026-02-10 22:29:52 +01:00
Oliver Kieselbach db6ea63489 Fix YAML formatting for Azure Static Web Apps workflow
fix api_location... must be "" as I'm using my own functions app
2026-02-10 20:17:21 +01:00
Oliver Kieselbach 8811b81c28 ci: add Azure Static Web Apps workflow file
on-behalf-of: @Azure opensource@microsoft.com
2026-02-10 20:13:51 +01:00