Overview
Alcatraz is Hoop’s in-process PII detection engine: a Go library compiled into the agent binary rather than a service you deploy. Detection is a function call on data the agent is already handling. That removes the deployment surface Microsoft Presidio carries: no Analyzer to scale, no Anonymizer, no Envoy, no service URLs, no HTTP round-trip per masked session. Configuration and behaviour are unchanged. You enable masking per resource role and pick entity types in the Hoop UI exactly as before, and the agent still parses the protocol, masks findings, and reports redaction statistics to the gateway. Only the detection step moves. The exception is coverage.PERSON, LOCATION and NRP are statistical rather than pattern-based, so the agent needs a small NER model on disk to serve them. That model is what the -alcatraz image tags carry, and most of what this page is about.
Requires Hoop
1.147.1 or later on both the gateway and every agent that serves masked connections. Existing Presidio and Google Cloud DLP deployments are unaffected.Architecture
DLP_PROVIDER and DLP_MODE in the connection parameters; the agent constructs the matching redactor and runs it for the life of the session. That is why both sides have a version requirement, and why sensitive payloads never leave the agent for analysis.
Enabling the provider
Set these on the gateway:
Nothing else is required:
MSPRESIDIO_ANALYZER_URL, MSPRESIDIO_ANONYMIZER_URL and GOOGLE_APPLICATION_CREDENTIALS_JSON can all be removed when you switch.
Restart the gateway, then confirm:
Choosing an agent image
Detection works on every agent image. Only the three statistical entity types need extra bytes on disk, and that is the whole difference between ahoophq/hoopagent flavour and its -alcatraz sibling. Tag list and invocation contract: Container Images.
Agents serving custom / command-line or RDP connections must run hoophq/hoopdev, and no hoopdev tag bakes the model in. See Mounting the model on hoopdev.
The statistical entity types
Alcatraz is pattern-based at its core: each built-in recognizer matches a structured identifier and, for 25 of the 45, validates a checksum. Those need nothing beyond the binary. Three types have no pattern to match, because a name or a city is only recognisable from context:PERSONLOCATIONNRP(nationality, religious or political group)
ALCATRAZ_NER_MODEL_PATH enables the module. It points at the models directory, the parent holding one subdirectory per model id, not the model’s own directory:
-alcatraz tags set this variable themselves. Leave it unset there.
The model is ~250 MB on disk. It loads lazily, on the first session that needs one of the three types, and is not released until the pod restarts, so size the pod for the loaded state rather than the idle one. See Sizing.
Kubernetes
With a baked-in model
Point the agent Helm chart at an-alcatraz tag and change nothing else.
Without the statistical types
If your rules only use structured identifiers, skip the model and run a plain flavour: ~250 MB smaller, no extra memory headroom.Mounting the model on hoopdev
Nohoopdev flavour bakes the model in. Provision it onto a volume and point the variable at it:
alcatraz models download into an emptyDir. Read-only is enough; the agent never writes there.
Docker Compose
DLP_PROVIDER=alcatraz on the gateway service and use an -alcatraz tag for the agent.
Provisioning the model yourself
Only needed for air-gapped builds,hoopdev agents, or a custom image. The -alcatraz tags already contain everything.
With the Alcatraz CLI
ALCATRAZ_NER_MODEL_PATH at --dest.
From Hoop’s mirror
Hoop publishes the same files to a bucket with a manifest naming them. This is what the-alcatraz image builds use. The objects are public-read: no AWS credentials, no aws CLI, no account. Listing is not allowed, which is why the recipe reads checksums.txt for the file names instead of enumerating the prefix.
current is a moving alias, not a revision. A rebuild may pick up a newer model; model/binary skew is caught when the agent loads it. Mirror the bucket into your own artifact store if you need a frozen copy.Building your own image
Dockerfile.agent in hoophq/hoop exposes the origin as a build argument, so an air-gapped build can swap in an internal mirror:
Sizing
Alcatraz adds no baseline cost: nothing is loaded until a session needs it.- The model never unloads. Once the first
PERSONsession runs, the pod holds that memory for life. A limit sized for the idle agent OOM-kills on that first session, not gradually. - Detection is CPU-bound and inline. Inference runs on the pure-Go ONNX backend (no cgo, no GPU) on the session’s own path. Under sustained masked traffic, CPU bounds throughput. Scale out replicas rather than up.
Verifying the model
The manifest ships with the model, so one command checks any copy:distroless has no shell. Export the container filesystem instead:
Troubleshooting
Sessions fail with an error about PERSON, LOCATION or NRP
Sessions fail with an error about PERSON, LOCATION or NRP
The rules request a statistical entity type and the agent has no model on disk. Switch to an If the variable is set but sessions still fail, it is probably pointing at the model’s own directory. It must point at the parent that contains
-alcatraz tag, or mount the model and set ALCATRAZ_NER_MODEL_PATH.KnightsAnalytics_distilbert-NER/.The agent pod is OOM-killed shortly after a masked session starts
The agent pod is OOM-killed shortly after a masked session starts
The model loaded and is never released. Raise the limit as described in Sizing, or move the connections that need statistical types to a dedicated deployment.
The UI still shows the Google Cloud DLP deprecation message
The UI still shows the Google Cloud DLP deprecation message
The gateway is not reporting
alcatraz as the effective provider. Check /api/serverinfo (see Enabling the provider) and confirm DLP_PROVIDER reached the process. A Helm value under the wrong key is the usual cause.A -alcatraz image build fails on `sha256sum -c`
A -alcatraz image build fails on `sha256sum -c`
A digest mismatch is never transient and the step must not be softened. The one benign cause is a build reading the manifest mid-publish. Retry once; if it fails again, the origin is serving something unexpected.
`kubectl exec` fails with `exec: sh: not found`
`kubectl exec` fails with `exec: sh: not found`
You are on a
distroless flavour, which has no shell by design. Use the minimal equivalent for interactive debugging, or export the filesystem as shown in Verifying the model.