Skip to content

fix(security): remove unused DEMI sync webhook - #836

Merged
danieltruong merged 1 commit into
bcgov:developfrom
danieltruong:chore/remove-demi-webhook
Aug 4, 2026
Merged

fix(security): remove unused DEMI sync webhook#836
danieltruong merged 1 commit into
bcgov:developfrom
danieltruong:chore/remove-demi-webhook

Conversation

@danieltruong

Copy link
Copy Markdown
Collaborator

Why

POST /api/document/sync accepts a document push from eagle-demi and upserts it into the epic
Document collection. Nothing calls it. eagle-demi has no code path that posts to eagle-api — its
only contact is a read-only seed pull from /api/public/search. The outbound eagle-api → docling
extraction path was deleted in 9fcf2ed, the same commit that added this webhook, on 2026-07-13.
It has been unmodified and uncalled since.

While it sat there unused it was also reachable and permissive:

  • No Keycloak gate. The swagger path carries no security: block, and
    api/middleware/swagger-security.js:23-31 treats that as public — it injects a synthetic public
    auth payload and calls next().
  • The only gate was a public literal. process.env.DOCLING_API_KEY || 'eagle-demi-api-key',
    compared with !== rather than a constant-time comparison. The chart defined that secret for
    dev only (values-dev.yaml); test and prod have no demi block, so the accepted key there was
    the string committed to this repository.
  • It wrote what the caller sent. Caller-supplied _id with upsert: true (so create or
    overwrite), passedAVCheck: true hardcoded, and read gaining 'public' whenever the caller sent
    isPublished.

What changed

Removed: api/controllers/demi.js, the /document/sync swagger path, test/controllers/demi.test.js
(4 tests, all of which hardcoded the fallback key), and the DOCLING_API_KEY wiring from
deployment.yaml / values.yaml / values-dev.yaml.

Also dropped two stale comments left by 9fcf2ed, both describing the extraction call that no longer
exists: a demi-extract job in jobQueue.js (only project-doc-export is defined) and "required to
call the extraction service" in the Helm template.

Kept deliberately: the DEMI fields on the Document schema (api/helpers/models/document.js:59-65).
They are inert, dev Mongo may still hold rows from the earlier DEMI intake path that shipped before
9fcf2ed, and dropping schema fields is data-affecting. documentSource is not DEMI-specific at all —
it carries PROJECT/COMMENT and is read by the DAO, four materialized-view reports and the
Typesense client.

Verification

  • npm test638 passing.
  • helm template renders clean for dev, test and prod, with zero DOCLING_API_KEY occurrences.
  • swagger.yaml parses; 87 paths remain, /document/sync gone, no path references the demi
    controller. Worth checking explicitly because the router is built from this file at boot, so a bad
    edit is a startup failure rather than a test failure.
  • Repo-wide grep for demi|docling returns only the two schema lines above.

Follow-up, not in this PR

The eagle-demi-api-key secret in the dev namespace is now unreferenced by eagle-api and can be
deleted — that is an oc mutation, so it is called out here rather than done here.

When DEMI is actually ready to push, the sync should be re-landed with a real gate: its own secret
(not DEMI's outbound docling credential reused inbound), no default value, fail-closed when unset,
and a constant-time comparison.

POST /api/document/sync had no swagger `security:` block, so
swagger-security.js treats it as public and injects a synthetic auth
payload. Its only gate was `DOCLING_API_KEY || 'eagle-demi-api-key'`
compared with !==, and the helm chart defines that secret for dev only —
in test and prod the accepted key is the literal committed here. The
handler then upserts a caller-supplied _id, hardcodes passedAVCheck:true
and grants public read when the caller says isPublished.

Nothing calls it. eagle-demi has no code path that posts to eagle-api;
its only contact is a read-only seed pull from /api/public/search. The
outbound docling extraction path was already removed in 9fcf2ed, the same
commit that added this webhook. Also drops that commit's two stale
comments, both describing the extraction call that no longer exists.

Document schema fields kept on purpose: dev Mongo may still hold rows
from the earlier DEMI intake path, and dropping schema fields is
data-affecting. Re-land the sync properly when DEMI is ready to push.
@danieltruong
danieltruong marked this pull request as ready for review August 4, 2026 08:02
@danieltruong
danieltruong merged commit 6567071 into bcgov:develop Aug 4, 2026
4 checks passed
danieltruong added a commit to digitalspace/eagle-demi that referenced this pull request Aug 4, 2026
bcgov/eagle-api#836 merged 2026-08-04. The route and its hardcoded key
fallback are gone, so there is nothing left to harden on that side.
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