diff --git a/docs/introduction/advanced-settings.mdx b/docs/introduction/advanced-settings.mdx
index e7297bd38..08f0e5472 100644
--- a/docs/introduction/advanced-settings.mdx
+++ b/docs/introduction/advanced-settings.mdx
@@ -309,6 +309,19 @@ Controls import path overrides during import resolution.
Enables and disables resolution of imports from `sys.path`.
+
+For this to properly work, you must also set `allow_external` to `True`.
+
+
+## Flag: `allow_external`
+> **Default: `False`**
+
+Enables resolving imports, files, modules, and directories from outside of the repo path.
+
+
+Turning this flag off may allow for bad actors to access files outside of the repo path! Use with caution!
+
+
## Flag: `ts_dependency_manager`
> **Default: `False`**
diff --git a/src/codegen/configs/models/codebase.py b/src/codegen/configs/models/codebase.py
index b8484e63b..8846d245a 100644
--- a/src/codegen/configs/models/codebase.py
+++ b/src/codegen/configs/models/codebase.py
@@ -21,6 +21,7 @@ def __init__(self, prefix: str = "CODEBASE", *args, **kwargs) -> None:
import_resolution_paths: list[str] = Field(default_factory=lambda: [])
import_resolution_overrides: dict[str, str] = Field(default_factory=lambda: {})
py_resolve_syspath: bool = False
+ allow_external: bool = False
ts_dependency_manager: bool = False
ts_language_engine: bool = False
v8_ts_engine: bool = False
diff --git a/src/codegen/sdk/codebase/codebase_context.py b/src/codegen/sdk/codebase/codebase_context.py
index 8840adce5..92d441e2f 100644
--- a/src/codegen/sdk/codebase/codebase_context.py
+++ b/src/codegen/sdk/codebase/codebase_context.py
@@ -381,7 +381,7 @@ def get_directory(self, directory_path: PathLike, create_on_missing: bool = Fals
"""
# If not part of repo path, return None
absolute_path = self.to_absolute(directory_path)
- if not self.is_subdir(absolute_path):
+ if not self.is_subdir(absolute_path) and not self.config.allow_external:
assert False, f"Directory {absolute_path} is not part of repo path {self.repo_path}"
return None
@@ -611,7 +611,7 @@ def get_edges(self) -> list[tuple[NodeId, NodeId, EdgeType, Usage | None]]:
def get_file(self, file_path: os.PathLike, ignore_case: bool = False) -> SourceFile | None:
# If not part of repo path, return None
absolute_path = self.to_absolute(file_path)
- if not self.is_subdir(absolute_path):
+ if not self.is_subdir(absolute_path) and not self.config.allow_external:
assert False, f"File {file_path} is not part of the repository path"
# Check if file exists in graph
diff --git a/src/codegen/sdk/core/codebase.py b/src/codegen/sdk/core/codebase.py
index 34d899441..f5b853a6e 100644
--- a/src/codegen/sdk/core/codebase.py
+++ b/src/codegen/sdk/core/codebase.py
@@ -213,6 +213,13 @@ def __init__(
self.ctx = CodebaseContext(projects, config=config, secrets=secrets, io=io, progress=progress)
self.console = Console(record=True, soft_wrap=True)
+ # Assert config assertions
+ # External import resolution must be enabled if syspath is enabled
+ if self.ctx.config.py_resolve_syspath:
+ if not self.ctx.config.allow_external:
+ msg = "allow_external must be set to True when py_resolve_syspath is enabled"
+ raise ValueError(msg)
+
@noapidoc
def __str__(self) -> str:
return f""
diff --git a/tests/unit/codegen/sdk/python/import_resolution/test_import_resolution.py b/tests/unit/codegen/sdk/python/import_resolution/test_import_resolution.py
index ebbe5d724..085b285a9 100644
--- a/tests/unit/codegen/sdk/python/import_resolution/test_import_resolution.py
+++ b/tests/unit/codegen/sdk/python/import_resolution/test_import_resolution.py
@@ -277,6 +277,8 @@ def func():
# Enable resolution via sys.path
codebase.ctx.config.py_resolve_syspath = True
+ # Allow resolving files and modules outside of the repo path
+ codebase.ctx.config.allow_external = True
# =====[ Imports cannot be found without sys.path being set ]=====
assert len(consumer_file.imports) == 1
@@ -372,6 +374,8 @@ def func():
# Ensure we don't have overrites and enable syspath resolution
codebase.ctx.config.import_resolution_paths = []
codebase.ctx.config.py_resolve_syspath = True
+ # Allow resolving files and modules outside of the repo path
+ codebase.ctx.config.allow_external = True
# =====[ Import with sys.path set can be found ]=====
assert len(consumer_file.imports) == 1
@@ -419,6 +423,8 @@ def func():
# Ensure we don't have overrites and enable syspath resolution
codebase.ctx.config.import_resolution_paths = []
codebase.ctx.config.py_resolve_syspath = True
+ # Allow resolving files and modules outside of the repo path
+ codebase.ctx.config.allow_external = True
# =====[ Default import works ]=====
assert len(consumer_file.imports) == 1