fix: resolve code-scanning alerts 11-15 (workflow permissions + log taint) (#184)
Some checks are pending
Deploy / deploy (push) Waiting to run
Deploy / release (push) Blocked by required conditions

* ci(dependency-review): set explicit read-only GITHUB_TOKEN permissions

Resolves code-scanning alert 11 (actions/missing-workflow-permissions).
The callable workflow only needs contents: read.

* fix(logging): remove taint-flagged values from 3CX and roster-sync logs

Resolves code-scanning alerts 12-15 (py/clear-text-logging-sensitive-data).
CodeQL taints the 3CX response dicts via the Secrets Manager-sourced
domain in the request URL, so entity IDs subscripted from those
responses (ivr_id, resource_id, queue_id) and the roster result dict
trip the query. None of the flagged values are secrets, but the log
lines are rewritten so the pattern cannot trip: entity IDs are dropped
in favor of the untainted destination DNs, and the roster summary logs
counts instead of the member-derived dict (which also keeps employee
names out of the logs).

* fix: update ci workflow SHA to latest version

* fix(logging): drop employee-derived DNs from forwarding log

Resolves new code-scanning alerts 16/17. The closed/holiday DNs added
in the previous commit derive from roster employee lookups in the
Slack bot, so CodeQL classifies them as private data. Log only the
resource type; ring_scheduler already logs the queue number.
This commit is contained in:
Adam Moussa 2026-07-27 13:48:14 -04:00 • committed by GitHub
parent fafefae500
commit f996f9600b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
4 changed files with 14 additions and 7 deletions

View file

@ -8,7 +8,7 @@ permissions:
jobs: jobs:
ci: ci:
uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main uses: Sea-Haven-Industries/.github/.github/workflows/ci-python-sam.yaml@f71002a9ed2938730b683249b28059c92a081af6
with: with:
source-dirs: "src/slack-bot src/weekly-post src/roster-sync src/ring-scheduler src/shared/shared tests" source-dirs: "src/slack-bot src/weekly-post src/roster-sync src/ring-scheduler src/shared/shared tests"
run-tests: true run-tests: true

View file

@ -1,6 +1,8 @@
name: Dependency Review name: Dependency Review
on: on:
pull_request: pull_request:
permissions:
contents: read
jobs: jobs:
review: review:
uses: Sea-Haven-Industries/.github/.github/workflows/callable-dependency-review.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main uses: Sea-Haven-Industries/.github/.github/workflows/callable-dependency-review.yaml@fd60e4c9041784f666ac0fdefb9bec3c7fbf5143 # main

View file

@ -119,5 +119,12 @@ def handler(event, context):
"updated": updated, "updated": updated,
"removed": removed, "removed": removed,
} }
logger.info("Roster sync complete: %s", result) logger.info(
"Roster sync complete: group=%s total_3cx=%d added=%d updated=%d removed=%d",
group_name,
len(threecx_extensions),
len(added),
len(updated),
len(removed),
)
return result return result

View file

@ -102,7 +102,7 @@ class ThreeCXClient:
json=payload, json=payload,
) )
resp.raise_for_status() resp.raise_for_status()
logger.info("Updated %s %s forwarding", resource, resource_id) logger.info("Updated %s forwarding", resource)
return resp.status_code return resp.status_code
def get_ring_group(self, extension_number: str) -> dict: def get_ring_group(self, extension_number: str) -> dict:
@ -142,7 +142,7 @@ class ThreeCXClient:
json=payload, json=payload,
) )
resp.raise_for_status() resp.raise_for_status()
logger.info("Set queue %s agents to %s", queue_id, extensions) logger.info("Set queue agents to %s", extensions)
return resp.status_code return resp.status_code
# ── IVR (auto-attendant) routing ───────────────────────────────────── # ── IVR (auto-attendant) routing ─────────────────────────────────────
@ -207,9 +207,7 @@ class ThreeCXClient:
json=payload, json=payload,
) )
resp.raise_for_status() resp.raise_for_status()
logger.info( logger.info("Set IVR (Receptionist) key-0=%s timeout=%s", key0_dn, timeout_dn)
"Set IVR (Receptionist) %s key-0=%s timeout=%s", ivr_id, key0_dn, timeout_dn
)
return resp.status_code return resp.status_code
@staticmethod @staticmethod