Skip to content

v0.6.0

Choose a tag to compare

@arcjet-rei arcjet-rei released this 25 Mar 20:26
· 44 commits to main since this release
Immutable release. Only release title and notes can be modified.
v0.6.0
0b615a5

What's Changed

This release brings the Python SDK to feature parity with the JavaScript SDK, adding local rule evaluation, sensitive info detection, and filter rules — all evaluated locally via a new embedded WebAssembly runtime.

Python SDK documentation is still in progress. The examples below cover the new rule types to get you started.

Local rule evaluation

Bot detection, shield, sensitive info, and filter rules now run locally via an embedded WebAssembly component (powered by wasmtime), giving faster decisions and reducing round-trips to the Arcjet API.

Sensitive info detection

Scan user-submitted content for PII (email addresses, credit card numbers, phone numbers, IP addresses) and block or allow by entity type:

from arcjet import arcjet, detect_sensitive_info, Mode, SensitiveInfoEntityType

aj = arcjet(
    key=arcjet_key,
    rules=[
        detect_sensitive_info(
            mode=Mode.LIVE,
            deny=[
                SensitiveInfoEntityType.EMAIL,
                SensitiveInfoEntityType.CREDIT_CARD_NUMBER,
            ],
        ),
    ],
)

decision = await aj.protect(
    request,
    sensitive_info_value="Please email me at test@example.com",
)

if decision.is_denied():
    # PII detected — block the request
    ...

Custom detection function

Supply a detect callback to extend the built-in detectors with your own logic. The function receives a list of tokens and returns a same-length list — either the entity type name or None:

def detect_custom(tokens: list[str]) -> list[str | None]:
    return [
        "CUSTOM_PII" if "api_key=" in token else None
        for token in tokens
    ]

aj = arcjet(
    key=arcjet_key,
    rules=[
        detect_sensitive_info(
            mode=Mode.LIVE,
            deny=["CUSTOM_PII", SensitiveInfoEntityType.EMAIL],
            detect=detect_custom,
        ),
    ],
)

Filter rules

Evaluate Wireshark-style expressions against request properties (IP, headers, path, method) to allow or deny traffic:

from arcjet import arcjet, filter_request, Mode

aj = arcjet(
    key=arcjet_key,
    rules=[
        filter_request(
            mode=Mode.LIVE,
            deny=[
                'ip.src.vpn or ip.src.tor',
                'http.request.uri.path contains "/admin"',
            ],
        ),
    ],
)

decision = await aj.protect(request)

Local fields for filter rules

Pass dynamic, per-request values into filter expressions via filter_local:

aj = arcjet(
    key=arcjet_key,
    rules=[
        filter_request(
            mode=Mode.LIVE,
            allow=['local.role eq "admin"'],
        ),
    ],
)

# In your route handler:
decision = await aj.protect(
    request,
    filter_local={"role": current_user.role},
)

Detailed changes

Features

  • Add WebAssembly component bindings & bindings generator in #70
  • Wire local (WebAssembly) rule evaluation into protect() in #71
  • Add sensitive info detection in #72
  • Add filter rules & global characteristics in #73
  • Cache DENY decisions in #75

Bug fixes

  • fix: set skip_custom_detect=True for local bot detection in #76

Full Changelog: v0.5.0...v0.6.0