SafeLens
Composable safety analysis and mechanistic-interpretability infrastructure for LLM workflows.
SafeLens gives safety experiments a shared runtime for model adapters, activation hooks, probes, monitors, attribution methods, pipeline execution, and structured reports.
Documentation · Quick Start · Explorer · Architecture · Model Sources · Hooks · Extend
Why SafeLens
LLM safety experiments tend to mix model loading, activation instrumentation, method code, runtime checks, attribution evidence, and report serialization in one-off scripts. SafeLens separates those concerns into stable interfaces, so a probe or monitor can move across model backends and pipeline configurations without rewriting the surrounding infrastructure.
|
Pluggable safety methods Register probes, monitors, and attributors by name, then assemble them from YAML. |
Activation-level runtime Cache activations, install temporary hooks, and run TransformerLens-style patching workflows. |
Model adapter boundary Target dummy, local, HuggingFace, Qwen3 Dense, ModelScope, and TransformerLens-compatible sources. |
|
Typed report contract Return Pydantic reports for risk scores, evidence tokens, attribution, and run summaries. |
CLI and Python APIs Run scans from safelens run, validate configs, inspect adapters, or call the runner directly.
|
Downstream adapter boundary Convert internal SafetyReport objects to FlagSafe-style policy payloads.
|
Architecture
SafeLens is organized as a layered runtime. User-facing entry points produce a validated config, the runner wires together model wrappers and registered methods, and the interpretability runtime provides reusable hook, cache, and patching primitives underneath the safety methods.
flowchart TB
classDef surface fill:#EEF6FF,stroke:#2563EB,color:#0F172A
classDef orchestration fill:#F8FAFC,stroke:#64748B,color:#0F172A
classDef method fill:#F0FDF4,stroke:#16A34A,color:#0F172A
classDef runtime fill:#FFF7ED,stroke:#EA580C,color:#0F172A
classDef model fill:#FAF5FF,stroke:#9333EA,color:#0F172A
classDef output fill:#FEF2F2,stroke:#DC2626,color:#0F172A
subgraph L0["Entry points"]
CLI["CLI<br/>safelens run / validate / schema"]
YAML["YAML pipeline config"]
Python["Python API<br/>PipelineRunner / build_model_wrapper"]
end
subgraph L1["Configuration and orchestration"]
Config["Pydantic config models<br/>PipelineConfig / ModelLoadConfig"]
Runner["PipelineRunner<br/>setup -> run -> summarize"]
Registry["Method registry<br/>create_probe / create_monitor / create_attributor"]
end
subgraph L2["Safety method layer"]
Probe["BaseProbe<br/>activation probes and interventions"]
Monitor["BaseMonitor<br/>batch or generation-time signals"]
Attributor["BaseAttributor<br/>input or training-data attribution"]
end
subgraph L3["Interpretability runtime"]
HookedRoot["HookedRoot + HookPoint<br/>temporary and persistent hooks"]
Cache["ActivationCache<br/>selection, slicing, residual decomposition"]
Patching["PatchSpec + generic_activation_patch<br/>residual, MLP, attention, head patches"]
Analysis["Analysis helpers<br/>logit attribution, SVD, FactoredMatrix"]
end
subgraph L4["Model bridge"]
Wrapper["ModelWrapper contract<br/>load_model / run_with_cache / generate"]
Bridge["Architecture adapters<br/>component hook names and tensor shapes"]
Adapters["ModelAdapterRegistry<br/>static inspection and cache plans"]
end
subgraph L5["Backends"]
Dummy["dummy"]
Local["local"]
HF["huggingface"]
Qwen["qwen3_dense"]
TL["transformer_lens compatible"]
MS["modelscope"]
end
subgraph L6["Outputs"]
Report["RunReport + SafetyReport"]
JSON["JSON artifact"]
FlagSafe["FlagSafeAdapter"]
Schema["JSON Schema"]
Docs["MkDocs docs"]
end
CLI --> Config
YAML --> Config
Python --> Runner
Config --> Runner
Runner --> Registry
Registry --> Probe
Registry --> Monitor
Registry --> Attributor
Runner --> Wrapper
Probe --> HookedRoot
Probe --> Cache
Probe --> Patching
Monitor --> Wrapper
Attributor --> Cache
HookedRoot --> Wrapper
Cache --> Wrapper
Patching --> Wrapper
Analysis --> Cache
Wrapper --> Bridge
Wrapper --> Adapters
Adapters --> Dummy
Adapters --> Local
Adapters --> HF
Adapters --> Qwen
Adapters --> TL
Adapters --> MS
Runner --> Report
Probe --> Report
Monitor --> Report
Attributor --> Report
Report --> JSON
Report --> FlagSafe
Config --> Schema
Report --> Schema
Config --> Docs
class CLI,YAML,Python surface
class Config,Runner,Registry orchestration
class Probe,Monitor,Attributor method
class HookedRoot,Cache,Patching,Analysis runtime
class Wrapper,Bridge,Adapters,Dummy,Local,HF,Qwen,TL,MS model
class Report,JSON,FlagSafe,Schema,Docs output
Quick Start
The default example uses model.source: dummy, so it does not download model
weights and is suitable for CI, smoke tests, and interface demos.
python -m pip install -r requirements-dev.txt
python -m pip install -e . --no-build-isolation
safelens validate --config examples/config.yaml
safelens run --config examples/config.yaml
Expected CLI summary:
{
"samples_scanned": 2,
"flagged_count": 1,
"max_risk_score": 1.0
}
The run writes a JSON report to ./safety_scan.json by default.
from SafeLens.pipelines.runner import PipelineRunner
report = PipelineRunner.from_yaml("examples/config.yaml").run()
print(report.summary)
Local Explorer
The interactive visualization workspace ships inside the Python package. From a source checkout, install the complete real-model job surface before the first launch, then start one process:
python -m pip install -e ".[explorer,models,modelscope,sae,attribution,nla,jlens,viz]"
python -m pip install "jlens @ https://codeload.github.com/anthropics/jacobian-lens/tar.gz/581d398613e5602a5af361e1c34d3a92ea82ba8e"
safelens explorer --artifact-root outputs/local-explorer --no-browser
The jlens extra only installs the J-Lens runtime dependencies; the jlens
package itself is distributed from the pinned Anthropic repository commit above
and is therefore installed as a separate step.
Explorer checks optional dependencies at job-preflight time, so a feature run
in an environment that only has .[explorer] is rejected with an explicit hint
that names the missing install command. Install the full command above in the
same environment that launches safelens explorer, and restart the process
after adding an extra; packages installed while Explorer is running are not
picked up.
| Feature | Extra | Provides |
|---|---|---|
| Viewer, Run Library, bundled artifacts | explorer |
FastAPI + Uvicorn |
| Prompt jobs on real models | models |
PyTorch + Transformers |
| ModelScope model source | modelscope |
ModelScope snapshot download |
| Attribution jobs | attribution |
Captum integrated gradients |
| SAE intervention and discovery | sae |
SAE Lens |
| NLA explanation jobs | nla |
Hugging Face Hub + Safetensors |
| J-Lens explanation jobs | jlens + pinned install (see above) |
J-Lens runtime dependencies |
| CircuitsVis HTML bridges | viz |
CircuitsVis |
SafeLens opens http://127.0.0.1:7860. The React application, artifact API,
deep links, and job API all use that one port; Node.js is not required at
runtime. The bundled example is immediately available, and compact
*.explorer.json files placed under the artifact root appear in the Run
Library.
Explorer automatically uses cuda:0 when CUDA is available and falls back to
CPU otherwise. Use SAFELENS_EXPLORER_JOB_DEVICE=auto, cpu, or cuda:1 for
an explicit override. See the complete Local Explorer setup
guide for model downloads, Gemma SAE setup, frontend
staging, remote deployment, health checks, and troubleshooting.
J-Lens uses a fitted, model-specific Jacobian checkpoint. Explorer registers the
public Neuronpedia checkpoint for Qwen/Qwen2.5-7B-Instruct (layers 0-26) and
defaults to layer 20 so its selection aligns with the public Qwen NLA profile.
The first run downloads the pinned checkpoint to .cache/safelens/jlens.
Configure another local checkpoint under the Explorer artifact root or a Hugging
Face repository in the Explanation panel, or set SAFELENS_JLENS_SOURCE,
SAFELENS_JLENS_FILENAME, SAFELENS_JLENS_REVISION, and
SAFELENS_JLENS_MODEL before launching Explorer.
For an isolated container instead:
docker build -t safelens-explorer .
docker volume create safelens-data
docker run --rm -p 127.0.0.1:7860:7860 \
-v safelens-data:/data safelens-explorer
See apps/local_explorer/README.md for frontend development, remote deployment, persistence, and health-check details.
Installation
SafeLens is currently installed from source.
| Use case | Command |
|---|---|
| Core package | python -m pip install -e . --no-build-isolation |
| Development and docs | python -m pip install -r requirements-dev.txt |
| HuggingFace, local, Qwen3 Dense, TransformerLens-compatible wrappers | python -m pip install -e ".[models]" --no-build-isolation |
| ModelScope wrapper | python -m pip install -e ".[modelscope]" --no-build-isolation |
| Local Explorer | python -m pip install -e ".[explorer]" |
| Explorer with real-model jobs | python -m pip install -e ".[explorer,models,modelscope,sae,attribution,nla,jlens,viz]" |
J-Lens jobs also need the pinned jlens package, which is not published on
PyPI:
python -m pip install "jlens @ https://codeload.github.com/anthropics/jacobian-lens/tar.gz/581d398613e5602a5af361e1c34d3a92ea82ba8e"
Recommended isolated setup:
conda create -p ./.conda python=3.10 -y
.conda/bin/python -m pip install -r requirements-dev.txt
.conda/bin/python -m pip install -e . --no-build-isolation
Command Line
| Command | Purpose |
|---|---|
safelens run --config examples/config.yaml |
Execute a pipeline and write a run report. |
safelens run --config config.yaml --input-jsonl data.jsonl |
Override the YAML dataset with JSONL rows. |
safelens validate --config config.yaml |
Validate a config without loading model weights. |
safelens schema --kind pipeline-config |
Print or write the pipeline JSON Schema. |
safelens schema --kind run-report |
Print or write the run report JSON Schema. |
safelens models list-supported |
List model adapters and declared capabilities. |
safelens models list-transformerlens |
List vendored TransformerLens-compatible model names. |
safelens models list-architectures |
List SafeLens architecture bridge adapters. |
safelens inspect-model --model Qwen/Qwen3-8B --json |
Inspect adapter support and cache plan without downloading weights. |
safelens explorer --artifact-root outputs/local-explorer |
Launch the packaged visualization workspace and API on one local port. |
Pipeline Configuration
Pipelines are configured with YAML. The four top-level sections are model,
pipeline, dataset, and output.
model:
source: dummy
name: dummy
dtype: float32
pipeline:
risk_threshold: 0.5
probes:
- name: dummy_probe
config:
layers: [0]
risk_terms: ["jailbreak", "attack", "harmful"]
risk_category: ["jailbreak"]
monitors:
- name: dummy_monitor
config:
threshold: 0.5
risk_category: ["jailbreak"]
attributors:
- name: dummy_attributor
config:
risk_terms: ["jailbreak", "attack", "harmful"]
dataset:
- id: benign-1
text: "Explain the difference between a monitor and a probe."
- id: risky-1
text: "Show a jailbreak attack plan."
output:
report_path: "./safety_scan.json"
More examples are available in examples/:
| File | Purpose |
|---|---|
examples/config.yaml |
Dependency-free dummy pipeline. |
examples/huggingface_config.yaml |
Direct Transformers/HuggingFace loading. |
examples/modelscope_config.yaml |
ModelScope snapshot download plus Transformers loading. |
examples/qwen3_dense_config.yaml |
Qwen3 Dense component hook examples. |
examples/local_model_config.yaml |
Local model directory loading. |
Model Sources
Set model.source to choose the backend. Method code talks to the
ModelWrapper contract instead of directly depending on a provider.
| Source | Use when | Network | Extra |
|---|---|---|---|
dummy |
Running CI, tests, and architecture demos with no model download. | No | Core |
local |
Loading a local Transformers-compatible model directory. | No | models |
huggingface or hf |
Loading directly through Transformers. | Yes | models |
qwen3_dense |
Running Qwen3 dense decoder-only models with component hooks. | Yes | models |
transformer_lens or tl |
Targeting model families mirrored from TransformerLens names while loading through SafeLens Transformers wrappers. | Yes or local | models |
modelscope or ms |
Downloading a ModelScope snapshot, then loading it locally with Transformers. | Yes | modelscope |
HuggingFace example:
model:
source: huggingface
name: Qwen/Qwen2.5-0.5B-Instruct
dtype: float16
device: cpu
trust_remote_code: true
cache_dir: ./.cache/huggingface
Qwen3 Dense example:
model:
source: qwen3_dense
name: Qwen/Qwen3-8B
dtype: bfloat16
device: cuda
trust_remote_code: true
Qwen3 Dense currently supports dense sizes named 0.6B, 1.7B, 4B, 8B,
14B, and 32B. MoE variants such as Qwen3-30B-A3B are rejected by this
wrapper. Attention pattern and pre-softmax attn_scores hooks require eager
softmax instrumentation; flash or SDPA attention paths may need an eager
attention implementation.
TransformerLens-compatible example:
model:
source: transformer_lens
name: gpt2-small
dtype: float32
device: cpu
This source mirrors TransformerLens-style model naming and analysis ergonomics,
but SafeLens still loads through its own Transformers wrappers and does not
require the transformer-lens package.
ModelScope example:
model:
source: modelscope
name: Qwen/Qwen2.5-0.5B-Instruct
dtype: float16
device: cpu
trust_remote_code: true
cache_dir: ./.cache/modelscope
local_dir: ./models/qwen2.5-0.5b
Hook And Patching Runtime
SafeLens includes a lightweight TransformerLens-style operation layer for mechanistic-interpretability and safety probing workflows. The goal is to make activation-oriented methods reusable across model wrappers while keeping the core package dependency-light.
| Primitive | Purpose |
|---|---|
HookPoint |
Identity hook point with temporary, permanent, ordered, and removable hooks. |
HookedRoot |
Shared hook management for named hook points. |
ActivationCache |
Dictionary-like cache with alias lookup, slicing, stacking, residual decomposition, and logit attribution helpers. |
temporary_hooks |
Install hooks for one run and reliably remove them afterward. |
cache_activations |
Run a model while collecting selected activations. |
PatchSpec |
Describe one activation replacement or additive patch. |
generic_activation_patch |
Run a grid of patches and score every patched output. |
get_act_patch_* |
Convenience helpers for residual streams, MLP outputs, attention outputs, head vectors, patterns, and scores. |
SafeLens accepts both native component names and TransformerLens-style names:
| Component | SafeLens style | TransformerLens style |
|---|---|---|
| Residual stream before attention | layer_0.resid_pre |
blocks.0.hook_resid_pre |
| Residual stream after attention | layer_0.resid_mid |
blocks.0.hook_resid_mid |
| Residual stream after MLP | layer_0.resid_post |
blocks.0.hook_resid_post |
| Attention output | layer_0.attn_out |
blocks.0.hook_attn_out |
| MLP output | layer_0.mlp_out |
blocks.0.hook_mlp_out |
| Query, key, value, head output | layer_0.q, layer_0.k, layer_0.v, layer_0.z |
blocks.0.attn.hook_q, blocks.0.attn.hook_k, blocks.0.attn.hook_v, blocks.0.attn.hook_z |
Minimal patching example:
from SafeLens.core.hooks import ActivationCache
from SafeLens.core.patching import get_act_patch_resid_pre
clean_cache = ActivationCache({"layer_0.resid_pre": clean_resid_pre})
scores = get_act_patch_resid_pre(
model,
corrupted_batch,
clean_cache,
metric=lambda output: float(output["score"]),
layers=[0],
positions=[3],
)
Transformers-backed wrappers also expose TransformerLens-style helpers when the underlying tokenizer and architecture support them:
tokens = model.to_tokens("SafeLens checks", prepend_bos=False)
logits, cache = model.run_with_cache(
tokens,
names_filter=lambda name: name.endswith("hook_resid_post"),
return_cache_object=True,
)
resid_post = cache["resid_post", 0]
Reports And Adapters
Every run emits a RunReport containing per-sample SafetyReport objects. The
report model is designed to keep method outputs inspectable and serializable.
{
"generated_at": "2026-01-01T00:00:00Z",
"summary": {
"samples_scanned": 2,
"flagged_count": 1,
"max_risk_score": 1.0
},
"reports": [
{
"sample_id": "risky-1",
"flagged": true,
"risk_score": 1.0,
"risk_category": ["jailbreak"],
"evidence_tokens": [2, 3],
"probe_results": [],
"monitoring_signals": [],
"attributions": [],
"metadata": {
"input_keys": ["id", "text"]
}
}
]
}
Use the FlagSafe adapter boundary when a downstream policy layer needs a compact allow/block payload:
from SafeLens.adapters import FlagSafeAdapter
rules = FlagSafeAdapter.to_flagsafe_batch(report.reports)
Extension Points
SafeLens exposes four core contracts.
| Interface | Implement when you need to | Output |
|---|---|---|
ModelWrapper |
Load a model, register hooks, run with cache, and generate outputs. | Model output and cache |
BaseProbe |
Analyze or intervene on internal activations. | ProbeResult |
BaseMonitor |
Emit safety signals during a batch or generation step. | MonitoringSignal |
BaseAttributor |
Attribute risk to input tokens or training-data sources. | AttributionResult |
Register a probe:
from collections.abc import Sequence
from typing import Any
from SafeLens.core.base import BaseProbe, Batch, ModelWrapper, ProbeResult
from SafeLens.core.registry import register_probe
@register_probe("linear_probe")
class LinearProbe(BaseProbe):
def attach(self, model: ModelWrapper, layers: Sequence[int]) -> None:
self.layers = list(layers)
def detect(self, batch: Batch) -> ProbeResult:
return ProbeResult(risk_score=0.0, critical_layers=self.layers)
def intervene(self, batch: Batch, direction: Any, scale: float) -> None:
...
def detach(self) -> None:
...
Enable it from YAML:
pipeline:
probes:
- name: linear_probe
config:
layers: [8, 16, 24]
Built-in demo methods:
| Method | Purpose |
|---|---|
dummy_probe |
Keyword-based probe for validating probe integration and evidence tokens. |
linear_probe |
Logistic-regression probe over explicit feature vectors or captured activations, trained from labeled examples. |
dummy_monitor |
Threshold-based monitor for validating monitor integration. |
dummy_attributor |
Token attribution stub for validating attribution output. |
linear_probe can train from labeled train_data, a train_jsonl file, or the
active pipeline dataset when train_from_dataset: true is set. Dataset rows
may provide explicit features, or plain text/prompt plus label; in the
latter case the probe runs the base model, caches the configured layer
activation, and trains on that activation internally.
Set train_split and eval_split to train and report on different subsets of
one dataset.
Contrastive steering vectors can be built and applied in separate steps:
from SafeLens.steering import ContrastiveSteeringVector
steering = ContrastiveSteeringVector.fit(
model,
dataset,
layer="layer_12.resid_post",
train_split="train",
)
steering.save("steering_vector.json")
loaded = ContrastiveSteeringVector.load("steering_vector.json")
handle = loaded.apply(model, scale=1.0)
try:
output = model.generate("Prompt to steer")
finally:
handle.remove()
Package Layout
src/SafeLens/
adapters/ external adapter boundaries, including FlagSafe
app/ future demo application entry points
attribution/ attribution implementations
core/ contracts, registries, hooks, cache, patching, analysis helpers
monitors/ safety monitor implementations
pipelines/ YAML-driven pipeline runner
probes/ probe implementations
steering/ steering-vector method namespace
utils/ model wrappers, model registry, and architecture bridges
Documentation
| Topic | Link |
|---|---|
| Documentation site | https://pku-pillar-group.github.io/SafeLens/ |
| Explorer setup and operations | docs/explorer_setup.md |
| Configuration | docs/configuration.md |
| Development guide | docs/development.md |
| Add a model adapter | docs/guides/add_model_adapter.md |
| Add a probe | docs/guides/add_probe.md |
| Add a monitor | docs/guides/add_monitor.md |
| Hook naming | docs/guides/hook_naming.md |
| Qwen3 support | docs/guides/qwen3_support.md |
| API reference | docs/api/ |
| Privacy notes | docs/privacy.md |
Build the docs locally:
mkdocs build --strict
mkdocs serve
Quality Checks
Use the same checks as CI when changing code or docs:
pre-commit run --all-files
pytest --cov=SafeLens --cov-report=term-missing --cov-report=xml
npm run build --prefix apps/local_explorer
npm run test:e2e --prefix apps/local_explorer
npm run test:performance --prefix apps/local_explorer
python -m build
python -m twine check --strict dist/*
mkdocs build --strict
The CI matrix validates Python 3.10, 3.11, and 3.12 quality jobs, frontend build/E2E/performance gates, package metadata, and the MkDocs documentation build.
Current Status
SafeLens is an alpha research infrastructure project. The core contracts, pipeline runner, registries, model adapter boundary, hook and patching runtime, typed reports, tests, docs, and CI scaffolding are in place. The built-in safety methods are intentionally simple demo implementations; real probes, monitors, attributors, and steering methods should be added through the extension interfaces above.
Near-term engineering priorities:
- Connect production-grade safety probes, monitors, attributors, and steering methods.
- Expand real-model integration coverage across supported architecture adapters.
- Tighten FlagSafe integration around the target downstream policy schema.
- Add richer tutorials for activation patching, cached attribution, and model adapter development.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file safelens-0.1.0.tar.gz.
File metadata
- Download URL: safelens-0.1.0.tar.gz
- Upload date:
- Size: 877.9 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
dc23bde2ba2e4ea9a3c2008b7de920502f4d5b1e1b50c4f72f3d5b97948043ff
|
|
| MD5 |
872ac5f0c087a78c96a0c3fcd3382216
|
|
| BLAKE2b-256 |
8d329e0a69d1b9edc34ea8f7f4fef77b30c85ba29b15117abc8319d369ffc044
|
Provenance
The following attestation bundles were made for safelens-0.1.0.tar.gz:
Publisher:
publish.yml on PKU-PILLAR-Group/SafeLens
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safelens-0.1.0.tar.gz -
Subject digest:
dc23bde2ba2e4ea9a3c2008b7de920502f4d5b1e1b50c4f72f3d5b97948043ff - Sigstore transparency entry: 2832772123
- Sigstore integration time:
-
Permalink:
PKU-PILLAR-Group/SafeLens@e786957cb25fecca68bf63f079211f048ea9597f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/PKU-PILLAR-Group
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e786957cb25fecca68bf63f079211f048ea9597f -
Trigger Event:
workflow_dispatch
-
Statement type:
File details
Details for the file safelens-0.1.0-py3-none-any.whl.
File metadata
- Download URL: safelens-0.1.0-py3-none-any.whl
- Upload date:
- Size: 759.8 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
twine/7.0.0 CPython/3.13.14
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85af73ca2d8308a52ff60aa20cfe814162384ff9bd8c19ec18e5260f93b36cd7
|
|
| MD5 |
0798fb0adcc21920216ade3fd5bce5e5
|
|
| BLAKE2b-256 |
85c36f8980a867a47ad6a663d119dc26b6f4b83510bb290acefc0ed03fcc21e7
|
Provenance
The following attestation bundles were made for safelens-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on PKU-PILLAR-Group/SafeLens
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
safelens-0.1.0-py3-none-any.whl -
Subject digest:
85af73ca2d8308a52ff60aa20cfe814162384ff9bd8c19ec18e5260f93b36cd7 - Sigstore transparency entry: 2832772191
- Sigstore integration time:
-
Permalink:
PKU-PILLAR-Group/SafeLens@e786957cb25fecca68bf63f079211f048ea9597f -
Branch / Tag:
refs/heads/main - Owner: https://github.com/PKU-PILLAR-Group
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e786957cb25fecca68bf63f079211f048ea9597f -
Trigger Event:
workflow_dispatch
-
Statement type: