resksecure · Documentation

Bitmask-driven logits filtering

resksecure maps an integer capability mask to a policy of banned phrases and tool gates, then suppresses those tokens during generation. It is the low-level RBAC-to-decoding bridge behind ReskSafety's local mode.

  • Version 0.1.1
  • Python 3.13+
  • Proprietary licence
  • Alpha

Licence first

Not open source

resksecure is distributed under the RESK Software License v1.1. Personal, educational, research and evaluation use is free; use by a professional entity requires a commercial agreement. Read LICENSE in the repository before deploying it.

Install

pip install resksecure        # requires Python 3.13+
pip install -e .              # from the repository

Dependencies: resklogits, torch, transformers, pyyaml. The published 0.1.0 wheel predates the current dependency floors; a source install follows pyproject.toml.

Policy and bitmask model

A bit is a capability. Bit i is granted when mask & (1 << i) != 0. Roles are just integers you compute and pass in — there is no role store, no JWT handling and no mask builder.

read_email = 0
send_email = 1
read_sql   = 2

contributor = (1 << read_email) | (1 << send_email) | (1 << read_sql)   # 7
viewer      = 1 << read_email                                          # 1

Each mask maps to one policy in the YAML file (exact integer lookup, with a default: true fallback). A policy carries:

Quick start

from resksecure import BitmaskLogitsProcessor, load_policy, verify_tool_action

policy_set = load_policy("src/resksecure/config/example_policy.yaml")

processor = BitmaskLogitsProcessor(
    mask=7,
    model_name="microsoft/phi-2",
    tokenizer=tokenizer,
    policy_set=policy_set,
    device="cpu",              # default is "cuda"
)

outputs = model.generate(
    **tokenizer("List all users:", return_tensors="pt"),
    max_new_tokens=50,
    logits_processor=[processor],
)
processor.reset()              # mandatory between independent generations

verify_tool_action("send_email", user_mask=7, policy_set=policy_set)   # True
verify_tool_action("send_email", user_mask=1, policy_set=policy_set)   # False

Only batch size 1 is supported. The automaton state persists across generate() calls until reset().

Policy file

version: "1"
policies:
  - mask: 7
    name: contributor
    strict: false
    rules:
      - phrase: "drop table"
        mode: hard
    tools:
      read_email:
        required_bit: 0
      send_email:
        required_bit: 1
        trigger_phrases: ["send_email("]
  - mask: 23
    name: auditor
    strict: true
    default: true

A tool is allowed when its bit is set; when it is not, its trigger_phrases are appended to the hard ban list, so the model cannot emit the call prefix. verify_tool_action() re-checks the same bit after generation, as defence in depth.

PolicyWatcher polls the file and exposes current_policy; TrieCache caches built automata for 300 seconds, keyed by (mask, model_name) — invalidate it when you change the policy.

API

SymbolPurpose
load_policy(path)Parse a YAML policy set. Missing mask/required_bit raises KeyError.
PolicySet.get_policy_for_mask(mask)Exact lookup with default fallback; None means the processor is inert.
BitmaskLogitsProcessorApplies hard bans, soft penalties and EOS forcing during decoding.
verify_tool_action(tool, mask, policy_set)Post-hoc tool authorisation; unknown tools are denied.
get_allowed_tools(mask, policy_set)List tools granted by a mask.
build_ac_from_policy, get_or_build_acAutomaton construction helpers.
PolicyWatcherBackground hot reload of the YAML file.
TrieCacheTTL cache for built automata.

Limitations