IP Restriction
IP restriction updates change the whitelist of IP addresses that can use a specific API token during the verification process. When a token has an IP list, verification only succeeds if the caller IP matches one of the stored addresses.
The IAM service stores the whitelist in the token record itself. That lets you add, replace, or remove restrictions without generating a new token, while keeping the current privilege, prefix, and expiration settings unchanged.
You can update IP restrictions in 3 ways:
- Directly calling
updateRestriction. - Using the
privateActionManagerto validate ownership before updating. - Calling the
POST /api/manage/ip-restriction-updateendpoint from an authenticated client.
Updating IP Restrictions
You can update IP restrictions either directly in the library or through the manager-backed route. The direct helper updates the database with a user id and token, while the route adds ownership validation and request-level protections.
Using the library
To update a token restriction directly, you call updateRestriction. This
function hashes the provided token when needed and updates the
restricted_to_ip_address field for the matching user and token.
import { updateRestriction } from '@riavzon/auth'
const userId = 1234
const token = 'api_1234'
const nextIps = ['203.0.113.10', '198.51.100.22']
const results = await updateRestriction(userId, token, nextIps)
To remove all IP restrictions, pass null:
const results = await updateRestriction(userId, token, null)
On success you get back an object with:
{
ok: true,
date: new Date().toISOString(),
data: { msg: 'Restriction updated successfully' }
}
On error, updateRestriction returns the branch that failed.
If the update query affects no rows, it returns:
{
ok: false,
date: new Date().toISOString(),
reason: 'Token not found or unauthorized'
}
This happens when the helper cannot find a row that matches the hashed token
and userId.
If the database update throws, the catch block returns:
{
ok: false,
date: new Date().toISOString(),
reason: 'Internal server error'
}
Signature
The direct helper exposes the following signature:
export async function updateRestriction(
userId: number,
rawToken: string,
newIpAddress: string[] | null,
): Promise<Results<{ msg: string }>>
Parameters
The IP update helper accepts the following parameters:
| Field | Type | Description |
|---|---|---|
userId | number | The user id that owns the token. |
rawToken | string | The token to update. It can be hashed or Raw. |
newIpAddress | string[] | null | The new whitelist of allowed IPv4 addresses, or null to remove restrictions. |
publicIdentifier, and it does not run the
verification process for the token.
Only call it directly in trusted server-side code.With the privateActionManager
The safest internal method is using the privateActionManager. This function
validates the publicIdentifier, token id, token name, user id, and current
valid status before it dispatches the IP update.
const ipUpdateResults = await privateActionManager(
userId,
tokenId,
publicIdentifier,
tokenName,
{
action: 'ip-restriction-update',
newIpAddress: ['203.0.113.10']
}
)
The privateActionManager returns the response of updateRestriction
directly. Learn more at the
introduction page.
valid = 1. Because of that,
manager-backed IP updates cannot target an already revoked token, and the
manager returns Bad Request before it reaches updateRestriction.Using the route
Let's say you want to update the allowed IP addresses for a token from your authenticated client or BFF.
POST /api/manage/ip-restriction-update body:
{
"tokenId": 12,
"publicIdentifier": "public_identifier",
"name": "the token name",
"ipv4": ["203.0.113.10", "198.51.100.22"]
}
To remove all restrictions through the route, omit ipv4 or send an empty
array. The controller converts both cases to null before it calls the
manager.
On success you will get the following response:
HTTP/1.1 200 OK
Content-Type: application/json; charset=utf-8
{
"ok": true,
"date": "current date",
"data": { "msg": "Restriction updated successfully" }
}
Standard authentication, body validation, and other shared management-route errors are documented on the introduction page.
The route-specific failures come from the manager and the update helper:
If the publicIdentifier checksum is invalid, the route returns Invalid identity.
If the manager cannot match a currently valid token for the given tokenId,
publicIdentifier, name, and userId, it returns Bad Request. That means
the token is already revoked, belongs to a different user, or the request body
does not point to an active row.
If the manager finds the token but the update query affects no rows, the route
returns Token not found or unauthorized. That is the exact failure returned by
updateRestriction when it cannot update the row with the current userId and
token hash.
If the database update throws, updateRestriction returns
Internal server error. If privateActionManager itself fails unexpectedly,
the route can also forward Server Error.
All of these route-specific failures are returned as 400 Bad Request by the
controller:
HTTP/1.1 400 Bad Request
Content-Type: application/json; charset=utf-8
{
"ok": false,
"date": "current date",
"reason": "reason from privateActionManager or updateRestriction"
}
Rate Limits
The endpoint also enforces rate limits controlled under the following configuration options:
rate_limiters.apiTokensLimiters.operationRateLimits.ipRestrictionUpdate- The main limiter for the IP restriction update endpoint. The default allows 5 updates in a window of 10 minutes and will trigger a block for 30 minutes if this limit is met. Consecutive triggers in this period will block the client permanently.rate_limiters.apiTokensLimiters.generalUnionLimiter- AburstLimiterand aslowLimiterunion limiter. It enforces no more than one request per second, and only 50 per minute. No consecutive triggers in this limiter are provided, and triggering it again will result in a permanent ban. The limiter is restarted on successful IP updates.burstLimiter- Will block the client for 15 minutes.slowLimiter- Will block for 1 hour.
IP Restriction Update Process
IP restriction updates apply to future verification requests as soon as the database write succeeds.
Normalize the requested list
The route validates the body with the ipRestrictionUpdate schema. After that,
the controller converts a non-empty ipv4 array to the new whitelist, and it
converts an empty array or omitted field to null so the restriction is
removed.
Validate ownership
When you use the manager or route, the system validates the
publicIdentifier checksum and confirms that the token belongs to the current
user and is still valid. This check happens before updateRestriction runs.
Update the token record
The direct helper hashes the token if needed and updates the
restricted_to_ip_address column for the matching userId and token. A
non-empty array is stored as JSON. A null value removes the restriction.
Enforce the new whitelist during verification
After the update succeeds, future verification requests use the new whitelist.
If the token has restricted addresses and the caller IP is not in that list,
the verification flow returns Invalid Host.
Configuration Reference
These configuration keys control IP update throttling in the service.
Rate limiters
The IP update flow relies on the following limiter configuration:
| Limiter | Description |
|---|---|
rate_limiters.apiTokensLimiters.operationRateLimits.ipRestrictionUpdate | The main rate limiter for the IP update endpoint |
rate_limiters.apiTokensLimiters.generalUnionLimiter | General burst limiter |