Blog

Legacy API access for AI: add auth, RBAC, and metering

·8 min read

AI is being pointed at systems that weren’t designed for it

The most valuable data in most enterprises isn’t in a modern SaaS product — it’s locked inside an ERP system from 2007, an on-prem data warehouse behind a VPN, or a homegrown internal API that nobody has touched in six years. As AI agents become a practical tool for automating workflows, the pressure to connect them to these systems is growing fast.

The problem is that legacy APIs and AI agents are fundamentally mismatched:

  • Legacy APIs were built on a trusted-network model. Authentication is often basic auth, a static API key in a fixed header, or no auth at all — because the system only ever received calls from other internal services on the same network. Nobody anticipated a non-deterministic agent calling it hundreds of times in a loop.
  • Legacy APIs have no scoping. A credential that can read customer records can usually also delete them. There is no concept of issuing a narrower credential to a consumer with a more limited role.
  • Legacy APIs have no usage controls. No rate limiting. No quotas. No automated alerts if something starts hammering the endpoint. This made sense when callers were other internal services with predictable, human-authored code. AI agents are a different category of consumer.
  • Legacy APIs expose too much. Response bodies often contain fields that have no business appearing in an AI model’s context window — internal identifiers, audit metadata, occasionally credentials or tokens embedded in responses.

Modifying the legacy system to address any of this is usually off the table. The code is old, the original engineers are gone, and the system is load-bearing enough that touching it carries serious risk. The answer isn’t to change the API — it’s to put a controlled facade in front of it.

The walled-garden problem

On-prem and network-isolated APIs create an additional layer of difficulty. The legacy system isn’t reachable from the internet, so you can’t simply point an AI framework’s tool configuration at a public URL. The endpoint lives at something like http://erp.internal.corp:8080 and is only accessible from within the corporate network or over VPN.

This matters because the AI agent orchestration layer — whether that’s a cloud-hosted LLM provider, an MCP server, or an agent framework — often runs partially or entirely outside that network boundary. You need a proxy that sits inside the network, can reach the legacy API directly, and presents a controlled, internet-accessible interface outward to the AI layer.

RequestRocket can be self-hosted inside your network or VPC. Your legacy API never needs to be exposed publicly, and the AI agent never needs network access to the internal system. The proxy mediates everything.

Auth translation: accept modern credentials, speak legacy auth

Every request through RequestRocket involves two separate credentials: a proxy credential that the caller (the AI agent) uses to authenticate to RequestRocket, and a target credential that RequestRocket uses to authenticate to the upstream legacy API. These are configured independently.

Start by registering the legacy API as a target. This is just the base URL of the internal system — no change to the system itself:

POST /clients/{clientId}/targets
{
  "targetName": "erp-internal-v2",
  "targetBaseURL": "http://erp.internal.corp:8080",
  "targetTestPath": "/api/health",
  "targetRegion": "us-east-1"
}

Next, store the legacy system’s credential as a target credential. This is whatever the old API actually expects — basic auth is common in legacy systems:

POST /clients/{clientId}/credentials
{
  "credentialType": "target",
  "credentialAuthType": "basic",
  "credentialName": "erp-service-account",
  "credentialRegion": "us-east-1",
  "credentialSecret": {
    "username": "svc-ai-integration",
    "password": "the-legacy-system-password"
  }
}

Now create a proxy credential for the AI agent. The agent presents a modern API key to RequestRocket — it never needs to know the legacy system’s credentials:

POST /clients/{clientId}/credentials
{
  "credentialType": "proxy",
  "credentialAuthType": "key",
  "credentialName": "ai-erp-agent",
  "credentialRegion": "us-east-1",
  "credentialSecret": {
    "key": "Authorization",
    "value": "your-api-key",
    "addToHeader": true
  }
}

Wire it together in a proxy. Set proxyDefaultRuleEffect to "deny" so the AI agent starts with no access and you explicitly grant what it needs:

POST /clients/{clientId}/proxies
{
  "proxyName": "erp-ai-facade",
  "proxyRegion": "us-east-1",
  "proxyProxyCredentialId": "<ai-erp-agent-credential-id>",
  "proxyTargetId": "<erp-internal-target-id>",
  "proxyTargetCredentialId": "<erp-service-account-credential-id>",
  "proxyDefaultRuleEffect": "deny"
}

The AI agent now calls the RequestRocket proxy endpoint using its own API key. RequestRocket authenticates the agent, strips its credential, authenticates to the legacy API using the stored target credential, and forwards the request. The legacy system sees its normal auth and has no idea an AI agent is on the other end.

Drop-in RBAC: scope what the AI can reach

With proxyDefaultRuleEffect: "deny", the AI agent has no access until you add explicit allow rules. This is the drop-in RBAC layer that legacy APIs never had.

For a workflow agent that needs to read customer records and create service tickets, grant exactly those paths — nothing else:

POST /clients/{clientId}/proxies/{proxyId}/rules
{
  "effect": "allow",
  "methods": ["GET"],
  "path": {
    "path": { "pattern": "^/api/v2/customers(/[^/]+)?$" },
    "presence": "must_exist"
  },
  "priority": 20,
  "notes": "AI agent: read customer records"
}
POST /clients/{clientId}/proxies/{proxyId}/rules
{
  "effect": "allow",
  "methods": ["POST"],
  "path": {
    "path": { "pattern": "^/api/v2/tickets$" },
    "presence": "must_exist"
  },
  "priority": 10,
  "notes": "AI agent: create service tickets only"
}

The legacy API’s full write surface — the ability to update records, delete entries, modify configuration — remains unreachable from this proxy regardless of what the AI agent generates as a request. The rules are enforced at the gateway before the request ever reaches the legacy system.

If the agent’s role changes, update or revoke the rules. No changes required to the legacy API, and no redeployment of agent code.

Metering: protect the legacy system from AI traffic patterns

Legacy internal APIs were designed around predictable call volumes from other internal services. An AI agent that retries aggressively on error, or a framework that parallelises tool calls, can generate request volumes the legacy system was never built to handle.

Meters are the enforcement mechanism. A meter with meterActive: true and configured limits will reject requests that exceed those limits with an HTTP 429, before the request reaches the legacy system:

POST /clients/{clientId}/proxies/{proxyId}/meters
{
  "meterName": "erp-ai-request-cap",
  "meterType": "request_count",
  "meterActive": true,
  "limits": {
    "minute": 30,
    "hour": 500,
    "day": 5000
  }
}

This cap of 30 requests per minute is generous for most AI agent workflows and conservative enough to protect a legacy API not designed for high concurrency. Adjust the thresholds based on what load testing or operational experience tells you the legacy system can absorb.

For legacy APIs that enforce their own quota and return a response indicating consumption — some billing or data APIs do this — a response_value meter can track that counter directly:

POST /clients/{clientId}/proxies/{proxyId}/meters
{
  "meterName": "erp-quota-tracker",
  "meterType": "response_value",
  "meterActive": true,
  "extraction": {
    "location": "body",
    "path": "meta.quotaUsed",
    "defaultValue": 0
  },
  "limits": {
    "day": 10000
  }
}

Filtering: keep sensitive data out of the AI context window

Legacy APIs often return more than they should — internal identifiers, audit fields, admin metadata, or occasionally embedded secrets that have accumulated in response bodies over years of organic growth. Any field that reaches the AI’s context window may be stored in logs, sent to third-party model providers, or influence model output in unexpected ways.

Filters applied to the proxy strip unwanted fields from responses before they leave RequestRocket. A destroy operation removes every field whose dot-notation path matches the given pattern:

POST /clients/{clientId}/proxies/{proxyId}/filters
{
  "operations": [
    {
      "effect": "destroy",
      "jsonPath": {
        "pattern": "\\.(internalId|auditLog|createdBy|modifiedBy|adminNotes|passwordHash)$",
        "flags": "i"
      },
      "notes": "Strip internal and audit fields before AI context"
    }
  ]
}

This runs on the response before the AI agent ever sees it. No changes to the legacy system, no custom middleware — the filter is applied at the gateway.

Observability: an audit trail the legacy system never had

One of the practical side effects of routing AI traffic through a proxy is that you get a complete request log the legacy system itself could never provide. Every request the AI agent makes is recorded with the path, method, response status, latency, and timestamp — accessible via the telemetry and request log APIs.

When something goes wrong — the AI agent starts generating unexpected requests, an error rate spikes, a batch job exhausts the meter limit — the data to diagnose it is already captured:

GET /clients/{clientId}/proxies/{proxyId}/requests?limit=100
GET /clients/{clientId}/telemetry?interval=hour&limit=48

This is audit-grade visibility into AI behaviour against a system that previously had no logging at the API layer. No changes to the legacy system, no log shipper configuration, no additional infrastructure.

The no-change-to-the-legacy-system constraint is real

Every capability described here — auth translation, RBAC, metering, response filtering, observability — is configured in RequestRocket, not in the legacy API. The legacy system sees the same request format it has always seen, authenticated with the same credentials it has always required, at a volume that respects its capacity.

The AI agent sees a modern, controlled API: a clean proxy endpoint, a scoped API key credential, hard limits on what it can call and how often, and responses that contain only the data the workflow needs.

The two systems never need to speak directly. RequestRocket is the translation layer between them.

Next steps

If you’re connecting AI agents to legacy or on-prem systems, start by mapping what data the agent actually needs and which paths that requires access to — that becomes your initial allow-list. Register the legacy API as a target, create the proxy, and add rules and a meter before you connect any agent. Read the RequestRocket documentation for the full proxy, credential, rule, meter, and filter reference, or start for free.

Enhance ISO 27001
Enhance SOC 2
Enhance GDPR
Enhance HIPAA

Add outbound API security
without changing code

Start on your own or talk to our team about improving the security of every API call you make.