> ## Documentation Index
> Fetch the complete documentation index at: https://docs.hiddenlayer.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Azure API Management CLI Usage Examples

This page shows common `hiddenlayer-apim` workflows.

## End-to-End Request Guardrails

```bash theme={null}
az login
hiddenlayer-apim init
```

Edit `.env`, list the available fragment packages, then deploy and apply request evaluation guardrails:

```bash theme={null}
hiddenlayer-apim packages
hiddenlayer-apim deploy --package v2-request-evals
hiddenlayer-apim list
hiddenlayer-apim apply openai-proxy --package v2-request-evals
hiddenlayer-apim status --package v2-request-evals
```

`apply` prints the inbound and outbound fragments it is about to inject and waits for `yes` before updating the APIM policy. Pass `--yes` to skip the prompt in CI or scripted runs:

```bash theme={null}
hiddenlayer-apim apply openai-proxy --package v2-request-evals --yes
```

## Request and Response Guardrails

Deploy and apply both v2 packages:

```bash theme={null}
hiddenlayer-apim deploy --packages v2-request-evals,v2-response-evals
hiddenlayer-apim apply openai-proxy --packages v2-request-evals,v2-response-evals
```

## Preview Before Applying

Use `--dry-run` to inspect the API policy XML before updating APIM:

```bash theme={null}
hiddenlayer-apim apply openai-proxy --packages v2-request-evals,v2-response-evals --dry-run
```

## Update Existing HiddenLayer Resources

Deploy is non-destructive by default. If APIM already has a HiddenLayer named value or policy fragment with different content, the command stops instead of overwriting it.

After reviewing the difference and deciding to replace the existing HiddenLayer-managed resources, run:

```bash theme={null}
hiddenlayer-apim deploy --packages v2-request-evals,v2-response-evals --overwrite
```

When changes are detected, `deploy --overwrite` lists the named values and policy fragments it will replace and waits for `yes` before continuing. Secret named values are shown by name only; their values are never printed.

## Test an Applied API

After `apply`, send a request through your APIM gateway:

```bash theme={null}
curl -i "https://<apim-name>.azure-api.net/<api-path>/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -H "Ocp-Apim-Subscription-Key: <subscription-key>" \
  -H "HL-Requester-Id: user-123" \
  -H "HL-Runtime-Session-Id: session-abc" \
  -d '{
    "model": "gpt-4o-mini",
    "messages": [
      {"role": "user", "content": "Say hello in one sentence."}
    ]
  }'
```

Add `-i` to show response headers. If HiddenLayer blocks a request or response, APIM surfaces:

```text theme={null}
HL-Runtime-Action: BLOCK
```

The two subsections below are illustrative only.

<Note>
  **Outcomes depend on HiddenLayer console policy configuration**

  The block, redact, and allow outcomes shown here are produced by the HiddenLayer policy attached to the project referenced by `HL_PROJECT_ID`. Whether a given request is blocked, redacted, or allowed — and which entities are redacted — depends entirely on the rules and detection categories configured in the HiddenLayer console. The same request can produce a different outcome in another project. See [Runtime Security Policy](/docs/products/runtime/policy) for how to configure policies, actions, and PII entities.
</Note>

### Example: Prompt Injection Is Blocked

In this example the project's policy has the **Prompt Injection** detection category set to **Block**. The `v2-request-evals` package calls HiddenLayer on the inbound path, sees the BLOCK action, and returns an OpenAI-shaped payload to the caller without forwarding the request to the model. The response body replaces the assistant content with a "message was blocked" payload and the `HL-Runtime-Action: BLOCK` header is set on the APIM response.

<Frame>
  <img src="https://mintcdn.com/hiddenlayer/KafqTKHPtqkVjdnX/docs/integrations/azure_apim/images/test_pi_req_and_resp.png?fit=max&auto=format&n=KafqTKHPtqkVjdnX&q=85&s=de872691737d68378e81380229c3efcf" alt="curl request containing a prompt injection attempt and the OpenAI-shaped response with content set to 'message was blocked'" width="2672" height="246" data-path="docs/integrations/azure_apim/images/test_pi_req_and_resp.png" />
</Frame>

### Example: PII Is Redacted in the Response

In this example the project's policy has a **PII** rule with action **Redact** that includes a US SSN entity. The request flows through to the backend, then the `v2-response-evals` package calls HiddenLayer on the outbound path and replaces the matched span with a token such as `[REDACTED:US_SSN]` before APIM returns the response to the caller.

Request:

<Frame>
  <img src="https://mintcdn.com/hiddenlayer/KafqTKHPtqkVjdnX/docs/integrations/azure_apim/images/test_redact_req.png?fit=max&auto=format&n=KafqTKHPtqkVjdnX&q=85&s=a2bd116e646130929ac416797b56196f" alt="curl request asking the model to concat numbers that resemble a US SSN" width="1801" height="172" data-path="docs/integrations/azure_apim/images/test_redact_req.png" />
</Frame>

Response:

<Frame>
  <img src="https://mintcdn.com/hiddenlayer/KafqTKHPtqkVjdnX/docs/integrations/azure_apim/images/test_redact_resp.png?fit=max&auto=format&n=KafqTKHPtqkVjdnX&q=85&s=3b01ea4cc4ce48788e348cc2b3690f32" alt="OpenAI-shaped response with the SSN-like sequence replaced by [REDACTED:US_SSN]" width="2672" height="182" data-path="docs/integrations/azure_apim/images/test_redact_resp.png" />
</Frame>

## Export Bicep

Generate a Bicep bundle for review or infrastructure-as-code deployment:

```bash theme={null}
hiddenlayer-apim export bicep --package v2-request-evals --out ./hl-bicep
```

The bundle's only required parameter is `apimServiceName`. Deploy with Azure CLI:

```bash theme={null}
az deployment group create \
  --resource-group <resource-group> \
  --template-file ./hl-bicep/main.bicep \
  --parameters apimServiceName=<apim-name>
```

You can also edit `./hl-bicep/main.bicepparam` and pass `--parameters ./hl-bicep/main.bicepparam` instead.

## Deploy From a Release Bicep Bundle

Customers who cannot run the CLI in their environment can deploy the pre-built Bicep bundle published with each GitHub release.

1. Download and extract `hiddenlayer-apim-vX.Y.Z-bicep.zip` from the desired release.
2. Pick the package directory to deploy, for example `v1-interactions/`, `v2-request-evals/`, or `v2-response-evals/`.
3. Set `apimServiceName` to your existing APIM service name. You can either edit the package's `main.bicepparam` or pass the value on the command line with `--parameters apimServiceName=<apim-name>`. The resource group comes from `az deployment group create --resource-group` and is not a Bicep parameter.
4. Preview and deploy one package directory at a time:

```bash theme={null}
# Authenticate and select the target subscription
az login
az account set --subscription "<subscription-id>"

# Preview the deployment
az deployment group what-if \
  --resource-group <resource-group> \
  --template-file ./v2-request-evals/main.bicep \
  --parameters apimServiceName=<apim-name>

# Deploy the package's fragments
az deployment group create \
  --resource-group <resource-group> \
  --template-file ./v2-request-evals/main.bicep \
  --parameters apimServiceName=<apim-name>
```

To deploy more than one package, run `az deployment group create` once per package directory.

<Warning>
  **Bicep does not deploy HiddenLayer credentials**

  The Bicep templates create only the package's policy fragments. They do not read `.env` and do not create the HiddenLayer named values that the fragments reference. Before enabling the fragments on an API, create these APIM named values using your approved secret-management process (for example, Key Vault-backed named values):

  * `hl-client-id`
  * `hl-client-secret` (mark as secret, or reference Key Vault)
  * `hl-project-id`
  * `hl-host`
  * `hl-tenant-id`
  * `hl-oauth-cache-seconds`
</Warning>

After deployment completes, the fragments are available in API Management. To enable them on an API without running the CLI, open the target API in the Azure portal policy editor and add the package's `<include-fragment fragment-id="..." />` entries to the appropriate `<inbound>` and `<outbound>` sections. The package's `package.json` manifest and `fragments/` directory show which fragment IDs belong to each package.

## Remove Guardrails From an API

Remove the fragments deployed by a specific package:

```bash theme={null}
hiddenlayer-apim remove openai-proxy --package v2-request-evals
```

`remove` previews the fragment IDs it will delete and waits for `yes` before updating the policy. When multiple HiddenLayer packages are applied, shared fragments such as `hl-oauth-token-management` are preserved so the remaining packages keep working.

Remove every detected HiddenLayer fragment in one step:

```bash theme={null}
hiddenlayer-apim remove openai-proxy --all
```

Skip the confirmation prompt in CI or scripted runs with `--yes`:

```bash theme={null}
hiddenlayer-apim remove openai-proxy --all --yes
```

`remove` only touches HiddenLayer `<include-fragment>` references and the correlation-ID setup it injects; unrelated APIM policy rules in `<inbound>`, `<backend>`, `<outbound>`, and `<on-error>` are preserved.
