Skip to content

Python: Add directory allowlist configuration for SessionsPythonTool file#13467

Merged
eavanvalkenburg merged 2 commits intomicrosoft:mainfrom
moonbox3:sessions-py-plugin
Jan 23, 2026
Merged

Python: Add directory allowlist configuration for SessionsPythonTool file#13467
eavanvalkenburg merged 2 commits intomicrosoft:mainfrom
moonbox3:sessions-py-plugin

Conversation

@moonbox3
Copy link
Collaborator

Motivation and Context

When SessionsPythonTool is used with an AI model, providing explicit directory boundaries for file operations gives developers fine-grained control over which parts of the filesystem the plugin can access. This follows the pattern established by HttpPlugin.allowed_domains.

  • Add allowed_upload_directories parameter to control which local directories can be used for file uploads
  • Add allowed_download_directories parameter for optional restrictions on file download destinations
  • Implement path canonicalization to resolve symlinks and normalize paths

Usage:

tool = SessionsPythonTool(
    credential=credential,
    allowed_upload_directories={"/app/data/uploads", "/app/user_files"},
    allowed_download_directories={"/app/data/downloads"},  # optional
)

Description

  • upload_file now requires allowed_upload_directories to be configured (deny-by-default)
  • download_file optionally supports allowed_download_directories (permissive-by-default, since it's not exposed as a kernel function)
  • Both parameters accept set[str] or list[str] for convenience
  • Paths are canonicalized using os.path.realpath() before validation

Contribution Checklist

@moonbox3 moonbox3 requested a review from a team as a code owner January 23, 2026 05:06
@moonbox3 moonbox3 added the python Pull requests for the Python Semantic Kernel label Jan 23, 2026
@moonbox3 moonbox3 self-assigned this Jan 23, 2026
@moonbox3 moonbox3 added the core plugin Anything related to core plugins label Jan 23, 2026
@moonbox3 moonbox3 requested a review from Copilot January 23, 2026 05:07
@moonbox3
Copy link
Collaborator Author

moonbox3 commented Jan 23, 2026

Python Test Coverage

Python Test Coverage Report •
FileStmtsMissCoverMissing
core_plugins/sessions_python_tool
   sessions_python_plugin.py1741293%94, 117, 119–120, 122, 124, 126, 134, 204–205, 239–240
TOTAL28126482582% 

Python Unit Test Overview

Tests Skipped Failures Errors Time
3811 23 💤 0 ❌ 0 🔥 1m 45s ⏱️

Copy link
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This pull request adds directory allowlist configuration for the SessionsPythonTool to provide security controls over file operations when the plugin is used with AI models.

Changes:

  • Added allowed_upload_directories parameter with deny-by-default behavior to restrict file uploads
  • Added allowed_download_directories parameter with permissive-by-default behavior for optional download restrictions
  • Implemented path canonicalization using os.path.realpath() to prevent path traversal attacks

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 8 comments.

File Description
python/semantic_kernel/core_plugins/sessions_python_tool/sessions_python_plugin.py Adds two new configuration parameters for directory allowlists, implements path validation methods, and updates upload_file and download_file methods to enforce security restrictions
python/tests/unit/core_plugins/test_sessions_python_plugin.py Updates existing tests to use real files instead of mocked file operations, adds comprehensive security tests for path validation and traversal prevention, and tests for list-to-set conversion
Comments suppressed due to low confidence (1)

python/semantic_kernel/core_plugins/sessions_python_tool/sessions_python_plugin.py:369

  • The upload_file method doesn't catch FileNotFoundError or other OSError exceptions that can occur when opening the file. If the file doesn't exist or can't be opened (e.g., due to permissions), the raw exception will propagate instead of being wrapped in a FunctionExecutionException with a helpful error message. Consider adding a try-except block around the file open operation to provide clearer error messages to users.
        try:
            with open(validated_path, "rb") as data:
                files = {"file": (remote_file_path, data, "application/octet-stream")}
                response = await self.http_client.post(url=url, files=files)
                response.raise_for_status()
                uploaded_files = await self.list_files()
                return next(
                    file_metadata for file_metadata in uploaded_files if file_metadata.full_path == remote_file_path
                )
        except HTTPStatusError as e:
            error_message = e.response.text if e.response.text else e.response.reason_phrase
            raise FunctionExecutionException(
                f"Upload failed with status code {e.response.status_code} and error: {error_message}"
            ) from e

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

@moonbox3 moonbox3 moved this to Sprint: In Review in Semantic Kernel Jan 23, 2026
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue Jan 23, 2026
github-merge-queue bot pushed a commit that referenced this pull request Jan 23, 2026
…file (#13467)

### Motivation and Context

When `SessionsPythonTool` is used with an AI model, providing explicit
directory boundaries for file operations gives developers fine-grained
control over which parts of the filesystem the plugin can access. This
follows the pattern established by `HttpPlugin.allowed_domains`.

- Add `allowed_upload_directories` parameter to control which local
directories can be used for file uploads
- Add `allowed_download_directories` parameter for optional restrictions
on file download destinations
- Implement path canonicalization to resolve symlinks and normalize
paths

Usage:

```python
tool = SessionsPythonTool(
    credential=credential,
    allowed_upload_directories={"/app/data/uploads", "/app/user_files"},
    allowed_download_directories={"/app/data/downloads"},  # optional
)
```


<!-- Thank you for your contribution to the semantic-kernel repo!
Please help reviewers and future users, providing the following
information:
  1. Why is this change required?
  2. What problem does it solve?
  3. What scenario does it contribute to?
  4. If it fixes an open issue, please link to the issue here.
-->

### Description

- `upload_file` now requires `allowed_upload_directories` to be
configured (deny-by-default)
- `download_file` optionally supports `allowed_download_directories`
(permissive-by-default, since it's not exposed as a kernel function)
- Both parameters accept `set[str]` or `list[str]` for convenience
- Paths are canonicalized using `os.path.realpath()` before validation

<!-- Describe your changes, the overall approach, the underlying design.
These notes will help understanding how your code works. Thanks! -->

### Contribution Checklist

<!-- Before submitting this PR, please make sure: -->

- [X] The code builds clean without any errors or warnings
- [X] The PR follows the [SK Contribution
Guidelines](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md)
and the [pre-submission formatting
script](https://github.com/microsoft/semantic-kernel/blob/main/CONTRIBUTING.md#development-scripts)
raises no violations
- [X] All unit tests pass, and I have added new tests where possible
- [ ] I didn't break anyone 😄
@github-merge-queue github-merge-queue bot removed this pull request from the merge queue due to failed status checks Jan 23, 2026
@eavanvalkenburg eavanvalkenburg added this pull request to the merge queue Jan 23, 2026
Merged via the queue into microsoft:main with commit e696dc7 Jan 23, 2026
27 checks passed
@github-project-automation github-project-automation bot moved this from Sprint: In Review to Sprint: Done in Semantic Kernel Jan 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core plugin Anything related to core plugins python Pull requests for the Python Semantic Kernel

Projects

Archived in project

Development

Successfully merging this pull request may close these issues.

4 participants