Skip to main content

ImportSpy

Policy-as-code admission for Python modules and dependencies.

Decide whether Python source satisfies your module, dependency, and runtime policies before admitting it for execution.

ImportSpy banner

PyPI Tests License

See a denial before execution

Install ImportSpy with Python 3.10 or newer:

pip install importspy

Create plugin.py:

import packaging
import typer

print("THIS MUST NOT RUN")

Create plugin.importspy.yml:

schema_version: 1
dependencies:
  packaging:
    allowed: true
    version: ">=24"
  typer:
    allowed: false

Both dependencies are installed with ImportSpy. Run:

importspy check plugin.py

The report includes:

ISPY-D101 [error] Dependency `typer` is not permitted by policy.
Decision: DENY
Target module was not executed.

The command exits with code 1. The print statement never runs. The complete example and automated regression test verify this behavior. A successful check also leaves the target unexecuted.

Start with your own module

importspy init path/to/plugin.py
# Review path/to/plugin.importspy.yml and edit its dependency approvals.
importspy check path/to/plugin.py
importspy check path/to/plugin.py --format json

init inspects source without importing it. The starter contract records source declarations and installed dependency identities; review it and add your own version, origin, environment, and evidence requirements. Unresolved imports are denied until reviewed.

One admission pipeline

Source → static preflight → dependency resolution → evidence → policy → ADMIT / DENY
                                                                          │
                                                    explicit load after ADMIT
                                                                          │
                                               execution → runtime validation
  • Structure: require functions, parameters, annotations, classes, and literal declarations.
  • Dependencies: resolve import names to distributions, including namespace contributors. Enforce allow/deny, required presence, versions, declarations, origins, and editable policy.
  • Host runtime: constrain Python, operating system, architecture, implementation, and environment.
  • Evidence: consume observations from explicitly selected providers and require verified signals.
  • Decisions: use the same structured facts and violations for human, JSON, and SARIF reports.

Checks that cannot establish a required static fact fail closed. A computed value or dynamically constructed interface is reported as unknown; ImportSpy does not execute the target to fill the gap.

A module and dependency contract

schema_version: 1
policy_id: payments-plugin
filename: plugin.py
functions:
  - name: process
    arguments:
      - name: amount
        annotation: int
    return_annotation: str
runtime:
  python: ">=3.10"
  environment:
    PAYMENT_MODE: production
dependencies:
  requests:
    version: ">=2.32,<3"
    declared: true
  internal-payment-sdk:
    origin:
      type: vcs
      repository: https://github.com/acme/payment-sdk
    editable: false
dependency_options:
  unresolved: deny
  undeclared: deny
  unlisted: deny

Distribution names are distinct from import names. Origin metadata is an observation, not verified provenance; missing direct-URL metadata does not prove installation from PyPI. Read the dependency reference for declaration modes, namespace behavior, and uncertainty.

Embed admission in a loader

from pathlib import Path
from importspy.domain import AdmissionRequest
from importspy.engine import AdmissionEngine

request = AdmissionRequest(
    subject=Path("plugin.py"),
    contract=Path("plugin.importspy.yml"),
)
engine = AdmissionEngine()
decision = engine.check(request)  # No target execution.
if decision.admitted:
    module, executed_decision = engine.load(request)  # Fresh admission, then execution.

load performs fresh admission and executes the inspected source bytes. Optional runtime validators run after execution and cannot undo side effects. It does not freeze the environment or recursively admit every transitive import. See the library workflow and security model.

Evidence and integrations

Supply-chain tools produce signals. ImportSpy turns relevant signals into admission decisions. Providers can integrate vulnerability results, attestations, or provenance without turning core into a scanner:

dependencies:
  cryptography:
    provenance:
      required: true

When cryptography is observed, this denies admission unless the selected provider supplies sufficient verified evidence. Add required: true if the dependency must also be present. ImportSpy does not manufacture cryptographic verification from package metadata. The extension API documents EvidenceProvider, PolicyValidator, RuntimeValidator, Reporter, and explicit entry-point loading.

Core checks work offline, with no account or telemetry. Network providers require explicit selection and network authorization. Plugins are trusted Python code.

CI

- uses: actions/setup-python@v5
  with:
    python-version: "3.12"
- run: python -m pip install importspy
- run: importspy check plugin.py --contract plugin.importspy.yml

Use --format json for automation or --format sarif for code-scanning integration. Exit codes are 0 admitted, 1 denied, 2 invalid configuration, and 3 tool failure. importspy check . checks explicit project subjects. See CI integration.

Scope and community

ImportSpy enforces policy at Python admission boundaries. It is not a sandbox, vulnerability scanner, package manager, or proof that admitted code is safe. It complements tools such as pip-audit, OSV, Sigstore, and SLSA by consuming their evidence through providers.

ImportSpy's earlier runtime-contract design and its community presentations remain part of the project's history. The GDG Basilicata talk describes that earlier generation; the 0.5 workflow begins with static admission.

MIT licensed. Created by Luca Atella.

ImportSpy logo

Metadata

Release files for importspy 0.5.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for importspy 0.5.0
File Size Uploaded
importspy-0.5.0.tar.gz 47.7 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for importspy 0.5.0
File Interpreter ABI Platform
importspy-0.5.0-py3-none-any.whl Python 3 none any Details

Total release size: 102.8 kB

Release files / importspy-0.5.0.tar.gz

Download URL importspy-0.5.0.tar.gz
Size 47.7 kB
Tags Source
SHA-256 checksum
How to use checksums
063856ca044962f0c469b51a8ded04a1627fa08bcd5ee99821b494d130de44a0
BLAKE2b-256 checksum
How to use checksums
a4da5678f93d04c0ea9ddf8ec3697f72b075a19a78641bf0fef3be16a0510d09
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.0 CPython/3.14.4 Darwin/25.5.0

Release files / importspy-0.5.0-py3-none-any.whl

Download URL importspy-0.5.0-py3-none-any.whl
Size 55.1 kB
Tags Python 3
SHA-256 checksum
How to use checksums
050956be3b9b52b549cf1d1b04b4ee64a358dab4b70a22a9267082503ce6b959
BLAKE2b-256 checksum
How to use checksums
da1c75dcdeed9d18b9cff9cbfc0b871c9db72c9bec06be3e0f03498941ed5001
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via poetry/2.4.0 CPython/3.14.4 Darwin/25.5.0

Release history Release notifications | RSS feed

This release

0.5.0 This release

2 release files

0.4.11

2 release files

0.4.9

2 release files

0.4.8

2 release files

0.4.7

2 release files

0.4.6

2 release files

0.4.5

2 release files

0.4.4

2 release files

0.4.3

2 release files

0.4.2

2 release files

0.4.1

2 release files

0.4.0

2 release files

0.3.3

2 release files

0.3.2

2 release files

0.3.1

2 release files

0.3.0

2 release files

0.2.1

2 release files

0.2.0

2 release files

0.1.12

2 release files

0.1.11

2 release files

0.1.10

2 release files

0.1.9

2 release files

0.1.8

2 release files

0.1.7

2 release files

0.1.6

2 release files

0.1.5

2 release files

0.1.4

2 release files

0.1.3

2 release files

0.1.2

2 release files

0.1.1

2 release files

0.1.0

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page