feat: initial scaffold for workflow-plugin-hover#1
Merged
Conversation
Per workflow PR#735 SPEC T9..T13 (DNS providers plan, Hover slice). Hover ships no official API. This scaffold mimics the browser-side auth flow used by pjslauta/hover-dyn-dns: internal/hover/totp.go — RFC 6238 TOTP (SHA-1, 30s step, 6 digits). Pure Go; no external deps. ParseBase32 accepts the Hover 2FA-setup seed format (whitespace/case-insensitive). Tested against RFC 6238 Appendix B vectors. internal/hover/client.go — Cookie-jar-backed http client: - GET /signin → parse CSRF _token (regex) - POST /signin (username, password, _token) - GET /signin/totp → parse fresh _token - POST /signin/totp (code, _token) - ListRecords / CreateRecord / UpdateRecord / DeleteRecord against /api/domains/<zone>/dns + /api/dns/<id> - ensureLogin cache: re-auths after 1h idle. plugin.json — declares resourceTypes [infra.dns], moduleTypes [iac.provider.hover], required_secrets[]: HOVER_USERNAME, HOVER_PASSWORD (sensitive), HOVER_TOTP_SECRET (sensitive). internal/serve.go + cmd/workflow-plugin-hover/main.go — gRPC entrypoint placeholder. Full IaC ResourceDriver registration lands once workflow#640 Phase 3 stabilises. Tests (9): - TOTP: 4 vectors (RFC 6238 Appendix B canonical 20-byte secret) + parser edge cases (whitespace, case, too-short, bad alphabet). - Client: two-step login hits expected paths in order; second ensureLogin within window is a cache hit; CSRF parse failure surfaces a clear error; NewClient refuses empty creds. CI: go vet + go test -race. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
intel352
added a commit
that referenced
this pull request
Jun 1, 2026
…— v0.5.0 (#30) * docs(hover): headless-browser auth design + ADR 0001 (defeat Imperva ABP) Replace cold-HTTP login with a real-Chrome (go-rod) session driver that runs Imperva's JS sensor + mints clearance; full-browser flow (TLS/JS/cookie consistency); system/cached/container Chrome; stealth. Login-only optimization deferred to an empirical scope test with the verified test account. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): harden browser auth design review * docs(hover): plan browser-backed auth implementation * docs(hover): review browser auth implementation plan * docs(hover): align browser auth plan with design * chore: lock scope for hover browser auth * test(hoverclient): add live browser auth viability gate go-rod probe (ProbeLiveBrowserAuth) + opt-in live test. Launches Chrome, strips navigator.webdriver, waits for Imperva clearance cookies, submits signin (incl. 2FA path) via in-browser fetch, then probes whether a plain Go http.Client can reuse the clearance for /api/domains (login-only optimization signal). Live test skips unless HOVER_LIVE_TEST=1; never logs secrets. go-rod is the driver picked by the both-drivers Imperva spike. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): backport go-rod driver spike evidence into design Records that both playwright-go and go-rod cleared Imperva headless in the scratch spike; go-rod picked for pure-Go runtime. De-risks Assumption #1. Full authenticated login still gated on test-account verification. No manifest change; no scope unlock required. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): record 2026-05-30 Imperva-bypass re-check (go-rod unchanged) No maintained Go-native Imperva-bypass lib; SOTA stealth tools all Python/Node (wrong language per ADR 0001). New 2026 signals (JA4 + UA-CH consistency) reinforce full-browser default. CDP-protocol fingerprinting flagged as most likely future-break vector for any CDP driver incl go-rod. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(hoverclient): keep profile dir on local launcher (Kill, not Cleanup) Live gate caught a panic: go-rod KeepUserDataDir() only works on a managed launcher; on a local launcher it panics (mustManaged). And Cleanup() deletes UserDataDir. Drop KeepUserDataDir(); use Kill() in cleanup so the persistent profile (and its Imperva clearance/cookies) survives across calls. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): backport live-gate result — Imperva cleared, 2FA model go-rod reached auth.json (need_2fa), not the Imperva 401 → Assumption #1 validated. Records Hover's email-default 2FA, new-device challenge, and the CI auth model (TOTP secret and/or persistent trusted profile). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * chore(hover): Go 1.26.3 + x/net v0.55.0 + gopls modernize Bumps go directive 1.26.0->1.26.3 (fixes stdlib html/template/net/net/http vulns GO-2026-4982/4980/4971/4918) and x/net 0.54.0->0.55.0 (GO-2026-5026). gopls modernize: maps.Copy for manual copy loops. govulncheck 7->2 affecting (remaining 2 are docker/docker via workflow SDK, no upstream fix). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): ADR 0002 fork go-rod -> GoCodeAlone/rod + design backport Records the maintained-fork decision (amends ADR 0001's driver source) and backports the CI auth model + scope amendment (dep source change + prod live-login proof via gh workflow on the self-hosted runner). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(hoverclient): use GoCodeAlone/rod fork for the browser driver Repoints the go-rod CDP driver to the maintained fork github.com/GoCodeAlone/rod v0.116.3 (ADR 0002). Build/vet/unit green; govulncheck adds no new vulns (only the pre-existing docker/docker SDK transitive remains, no upstream fix). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): backport production live proof (Imperva cleared, TOTP, 30 domains) CI probe on self-hosted runner vs production: go-rod fork clears Imperva, TOTP completes new-device 2FA, 30 domains read, go_http_reuse_viable=true. Adopts login-only transport (browser login -> Go HTTP for API) per the design's conditional, with full-browser fallback for the TLS-fingerprint risk and write paths. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * refactor(hoverclient): add browser backend configuration seam Introduce executionBackend interface routing Login/ListDomains/etc. to either httpBackend (injected http.Client — tests) or browserBackend (nil http.Client — production Chrome path). NewClientWithOptions parses explicit BrowserOptions; NewClient preserves backward-compat signature. Provider Initialize parses browser_path/download/headless/profile_dir config keys with HOVER_BROWSER_* env fallbacks via parseBrowserConfig. browserBackend live ops return ErrBrowserBackendUnavailable (Task 3). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(hoverclient): browser login mints Imperva clearance + hands cookies to HTTP reads Task 3: implement browserBackend.Login (Chrome launch via launchBrowserWithHandles, navigator.webdriver strip, UA/AcceptLanguage stealth, waitForClearanceCookies, submitBrowserSignin with TOTP, cookie handoff to c.http.Jar), typed errors (ErrBotChallenge / ErrChromeUnavailable / ErrEmail2FARequired), read delegation (ListDomains/GetDomain/ListRecords/GetDomainDelegation → HTTP backend after login), writes still return ErrBrowserBackendUnavailable (Task 4). Ten new tests in browser_backend_test.go drive real go-rod against local httptest servers. Add .hover-browser-profile/ to .gitignore. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * feat(hoverclient): execute hover dns writes in-browser (hybrid write path) Implement Task 4: CreateRecord, UpdateRecord, DeleteRecord, and SetNameservers on browserBackend now execute in-page via Chrome fetch (credentials:'include') so requests carry the live Imperva clearance and Chrome TLS fingerprint. Generalise browserSigninFetch into reusable browserFetchJSON/browserFetchWithHeaders helpers (probe + writes share one in-page fetch path). SetNameservers extracts CSRF from the control_panel page DOM in-browser then PUTs with X-CSRF-Token. Guards b.browser == nil with a clear "not initialised" error when Login was never run. All endpoints/payloads/typed-errors preserved from HTTP impls. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): browser-auth README + v0.5.0 manifests + live plugin test Rewrite README to document the real Chrome/go-rod auth architecture (Imperva ABP bypass, hybrid browser-login + HTTP-read + in-browser-write model, Chrome acquisition, BrowserOptions config keys + env aliases, TOTP/email-2FA requirements, browser profile dir, typed errors). Remove stale CSRF form-login description. Bump both plugin.json manifests from 0.0.0 to 0.5.0 (behavioral minor for the browser-auth backend). Update iacserver_live_test.go: gate on HOVER_LIVE_TEST=1, source browser opts via BrowserOptionsFromEnv + config keys from env, exercise the full provider Initialize → EnumerateAll → Import → Status path (typed gRPC server surface), skip cleanly when HOVER_LIVE_TEST is unset. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * docs(hover): security review + harden bot-challenge classification Task 6: security review (PASS — no Critical/High; one tracked UA-derivation resilience follow-up). Fixes Login mislabeling a cookie-read error as ErrBotChallenge (only a clearance timeout is a challenge now). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Hover DNS scaffold: TOTP (RFC 6238) + cookie-jar login client + plugin manifest. 9 tests pass.