Repository navigation
fix(aicore): make content filter misconfiguration visible - #458
Merged
Merged
Conversation
- Add ContentFilteringNotConfiguredError for fail-closed (strict) mode - Emit logger.warning on both fail-open branches in transform_request - Add _assert_filtering_ready() pre-flight guard in completion()/acompletion() - Expose strict mode via AICORE_FILTER_STRICT env var and set_filtering(strict=) - Export new exception from aicore and filtering packages - Document strict mode and new env var in user-guide.md
ricardosrib
commented
Nov 6, 2026
ricardosrib
left a comment
Contributor
Author
There was a problem hiding this comment.
Security Review: fix/aicore-content-filter-fail-open
Verdict: ✅ No security issues
| # | Criterion | Status | Finding |
|---|---|---|---|
| S1 | Tenant subdomain validation | ➖ | No tenant/subdomain parameters introduced |
| S2 | URL construction (structured, not str.replace) | ➖ | No URL construction |
| S3 | Credential emptiness checks | ➖ | No credential fields read |
| S4 | JWT tokens verified before trust | ➖ | No JWT handling |
| S5 | No hardcoded credentials/secrets | ✅ | Only env var name literals and log message strings |
| S6 | Sensitive data not logged | ✅ | Both new logger.warning calls use hardcoded reason strings — no request content, credentials, or PII in any log path |
| S7 | No path traversal from external input | ➖ | No filesystem operations |
| S8 | HTTP base URLs validated | ➖ | No HTTP requests constructed |
| S9 | Multi-tenant cache isolation | ➖ | Module-level globals (_active_cfg, _strict_mode, _configured) are process-scoped by pre-existing design — not per-tenant, not changed by this PR |
| S10 | New dependencies checked for CVEs | ➖ | No new dependencies |
| S11 | No verify=False in HTTP calls |
➖ | No HTTP calls |
| S12 | Audit log for mutating tenant operations | ➖ | No tenant-scoped mutations |
✅ Things Done Well
- Warning messages contain no request body, no credentials, no user input — only hardcoded literal strings, so there is no risk of accidentally surfacing sensitive prompt content into logs.
ContentFilteringNotConfiguredErrormessage is similarly inert — it describes the SDK state, not the request.- The PR itself remediates CWE-636 (Not Failing Securely), moving the module from silent fail-open to an observable and optionally fail-closed posture.
cassiofariasmachado
force-pushed
the
main
branch
from
November 10, 2026 22:47
347e85b to
2c4dd1d
Compare
ricardosrib
force-pushed
the
fix/aicore-content-filter-fail-open
branch
from
November 11, 2026 17:28
9f656a2 to
561ff50
Compare
tiagoek
approved these changes
Nov 11, 2026
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.
Description
Fixes a silent fail-open in the AI Core content filtering integration. When filtering was misconfigured or never set up, requests were sent unfiltered with no warning, no exception, and no way to enforce fail-closed behaviour.
This PR makes misconfiguration visible: a
logger.warningis emitted whenever a request would proceed without filtering.Also added an opt-in strict mode (
set_filtering(strict=True)orAICORE_FILTER_STRICT=true), which raisesContentFilteringNotConfiguredErrorinstead of sending an unfiltered request. Intentional opt-outs viadisable_filtering()orAICORE_FILTER_ENABLED=falseremain silent.Type of Change
How to Test
completion()without first callingset_aicore_config()orset_filtering(); confirm alogging.WARNINGcontaining"never configured"is emitted exactly once and the call proceeds.AICORE_FILTER_STRICT=trueand repeat step 1; confirmContentFilteringNotConfiguredErroris raised before the network call is made.set_filtering(ContentFiltering(), strict=True)(empty config) then a stubbedcompletion(); confirmContentFilteringNotConfiguredErroris raised.disable_filtering()thencompletion(); confirm no warning is logged.pytest tests/aicore -q— all tests should pass.Checklist
/security-reviewand addressed all ❌ findingsAdditional Notes
Collateral formatting changes
Running
ruff format .as part of CI prep reformatted inline comments and wrapped long lines in several unrelated user guides anddocs/GUIDELINES.md. These are whitespace-only changes with no semantic content.