Skip to content

fix(agent-os): enforce TLS for configured MCP URLs - #3793

Merged
MohammadHaroonAbuomar merged 2 commits into
microsoft:mainfrom
pararti:fix/mcp-auth-configured-url-tls
Sep 14, 2026
Merged

MohammadHaroonAbuomar merged 2 commits into
microsoft:mainfrom
pararti:fix/mcp-auth-configured-url-tls

Conversation

@pararti

Copy link
Copy Markdown

Related Issue

Fixes #3785

Problem & Solution

McpAuthPolicy.check() enforced require_tls only against the URL supplied by the caller. When the caller omitted that argument, a non-TLS URL already stored in the matching McpServerEntry was never evaluated.

This PR selects the effective URL as the caller URL or the configured entry URL. The caller URL retains priority because it describes the connection being checked. If both sources are empty, the existing behavior remains unchanged and the TLS gate is skipped, preserving S10.12 compatibility.

Impact on Your Work

Configured MCP server URLs now receive the same TLS scheme enforcement as caller-supplied URLs.

Timeline

None.

Alternatives Considered

  • Requiring every caller to repeat the configured URL would leave the configuration path unenforced.
  • Rejecting entries when both URL sources are empty would change the existing S10.12 conformance behavior and is outside the scope of this fix.

Type of Change

  • Bug fix (non-breaking change that fixes an issue)
  • New feature (non-breaking change that adds functionality)
  • Breaking change (fix or feature that would cause existing functionality to change)
  • Documentation update
  • Maintenance (dependency updates, CI/CD, refactoring)
  • Security fix

Package(s) Affected

Core & runtime:

  • agent-governance-toolkit-core
  • agent-primitives
  • agent-os
  • agent-mesh
  • agent-runtime
  • agent-sre
  • agent-compliance

Governance & security:

  • agent-mcp-governance
  • agent-rag-governance
  • agent-sandbox
  • agent-discovery
  • agt-policies
  • policy-engine

Platform & tooling:

  • agent-hypervisor
  • agent-lightning
  • agent-marketplace
  • agent-governance-toolkit-cli
  • agent-governance-toolkit-integrations
  • agent-governance-toolkit-protocols
  • agentmesh-integrations (framework integrations)

CLI plugins:

  • agent-governance CLI plugins (copilot-cli / claude-code / opencode / antigravity-cli)

Shared / other:

  • schemas
  • action (GitHub Action)
  • examples
  • docs / root

Testing

Unit Testing

Added an 18-case parameterized matrix covering:

  • require_tls=True and False
  • empty, HTTPS, and HTTP caller URLs
  • empty, HTTPS, and HTTP configured entry URLs
  • caller URL precedence
  • the compatible empty-both-sources behavior

Manual Testing

pytest agent-governance-python/agent-os/tests/test_mcp_auth_enforcement.py -q
35 passed, 1 deprecation warning

git diff --check passes. Ruff reports the same four existing file-level findings as main; none are introduced by the changed lines. The direct conformance module was not collectable in this local checkout because the compiled agent_control_specification._native module is unavailable; the regression matrix directly pins the S10.12 empty-both behavior.

Checklist

  • I have linked a related issue above, or completed "Problem & Solution", "Impact on Your Work", and "Alternatives Considered"
  • My code follows the project style guidelines (ruff check)
  • I have added tests that prove my fix/feature works
  • All new and existing tests pass (pytest) — the scoped suite passes; the full package suite was not run locally
  • I have updated documentation as needed
  • I have signed the Microsoft CLA — pending CLA bot verification

Attribution & Prior Art

  • This contribution does not contain code copied or derived from other projects without attribution
  • Any external projects that inspired this design are credited in code comments or documentation
  • If this PR implements functionality similar to an existing open-source project, I have listed it below

Prior art / related projects (if any):

The configured-URL fallback was previously discussed within this repository in #3512 and was raised again in #3785. No external project code was copied or adapted.

AI Assistance

  • I can explain every meaningful change in this PR: what it does, why, and what tradeoffs were considered
  • I have run tests and verification appropriate for this change
  • No part of this PR was autonomously submitted by an AI agent without my review
  • I have not used AI to generate review comments on others' PRs

Codex was used to inspect the issue, draft the regression matrix and minimal patch, and prepare this PR text. All changes were reviewed and explicitly approved by the contributor before submission.

IP, Patents, and Licensing

  • This contribution does not implement patent-pending or patent-encumbered techniques
  • This contribution does not require an NDA or licensing agreement to understand or use
  • Any AI tools used have terms compatible with the MIT License

Signed-off-by: Artem Parshin <me@apararti.ru>
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

@github-actions

Copy link
Copy Markdown

Welcome to the Agent Governance Toolkit! Thanks for your first pull request.
Please ensure tests pass, code follows style (ruff check), and you have signed the CLA.
See our Contributing Guide.

@github-actions

Copy link
Copy Markdown

PR Review Summary

Check Status Details
🔍 Code Review ⚠️ Missing No current-run comment
🛡️ Security Scan ⚠️ Missing No current-run comment
🔄 Breaking Changes ⚠️ Missing No current-run comment
📝 Docs Sync ⚠️ Missing No current-run comment
🧪 Test Coverage ⚠️ Missing No current-run comment

Verdict: ⚠️ AI review incomplete; ready for human review

AI review comments are untrusted advisory output. The summary reports workflow-generated completion status only, not model-authored pass/fail claims.

@github-actions github-actions Bot added tests size/M Medium PR (< 200 lines) labels Aug 20, 2026
@pararti

Copy link
Copy Markdown
Author

@microsoft-github-policy-service agree

@pararti
Artem (pararti) marked this pull request as ready for review August 21, 2026 15:08
@azure-pipelines

Copy link
Copy Markdown
Azure Pipelines:
There may be pipelines that require an authorized user to comment /azp run to run.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ran this branch's suite locally against its own tree (PYTHONPATH=src python -m pytest tests/test_mcp_auth_enforcement.py): 35 passed. The fix is correct.

Confirmed the defect on main: if entry.require_tls and url: means a registered entry configured
with url: http://mcp.internal/api and require_tls: true is allowed whenever the caller omits the
URL. Since the parameter was documented as "for logging/audit", omitting it is the natural thing for
a caller to do, so this was the default path rather than an edge case.

The parametrized test is the best part of this PR. Sweeping the full nine-way caller-URL by
configured-URL matrix crossed with require_tls states the property rather than sampling it, and it
pins the precedence in both directions: an https caller against an http entry is allowed, an
http caller against an https entry is denied. That second case is the one a hand-written test set
tends to miss, and getting it backwards would let a config value override where the connection is
actually going.

Overlap. #3797 fixes the same defect with the same mechanism and is functionally identical to
this branch, right down to effective_url = url or entry.url. It was opened against the same issue
(#3785). It carries twelve named tests reaching schemes this branch does not exercise (ws, wss,
ftp, bare hostname with no scheme), an end-to-end YAML case, and a new docs/mcp-auth-tls.md. The
two edit the same lines, so they will conflict.

My read for the maintainers is that #3797 is the one to land on coverage, and that this branch's
parametrized matrix is worth carrying across afterwards, because it is a tidier statement of the
precedence property than #3797's named pair. That is a genuine contribution and it should not be
lost just because the code change is the same on both.

Also worth knowing: #3849 closes the sibling hole (#3814, unregistered server names skipping the
gate entirely) in the fallback branch of the same method, and does not conflict with either of these.
The three of them together are what actually closes the TLS floor.

Nothing blocking on the change itself.

@MohammadHaroonAbuomar

Copy link
Copy Markdown
Collaborator

The only CI run on this head is from mid-August and its required checks have expired, so the merge gate cannot see them. Please rebase onto current main and force-push to trigger a fresh run. The content is already reviewed and approved; nothing else is needed.

@MohammadHaroonAbuomar MohammadHaroonAbuomar left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Verified: effective-URL fix for #3785 with an 18-case matrix, malformed entries fail closed, S10.12 behaviour preserved. Preferred over #3797, which is behaviourally identical but larger.

@MohammadHaroonAbuomar
MohammadHaroonAbuomar merged commit d5981fe into microsoft:main Sep 14, 2026
125 checks passed
Yuvraj Singh (yuvrajsingh2428) pushed a commit to yuvrajsingh2428/agent-governance-toolkit that referenced this pull request Oct 1, 2026
Signed-off-by: Artem Parshin <me@apararti.ru>
Co-authored-by: MohammadHaroonAbuomar <40180927+MohammadHaroonAbuomar@users.noreply.github.com>
Signed-off-by: yuvrajsingh2428 <offcyuvi2428@gmail.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size/M Medium PR (< 200 lines) tests

Projects

None yet

Development

Successfully merging this pull request may close these issues.

MCP auth: require_tls gate never consults the configured entry.url

3 participants