Plugins
IP Access Control (Memory)
Mutable allow/deny lists with runtime controls. Enforce source IP checks and manage lists at runtime.
How it works
- Keeps
allow
anddeny
lists in memory, configurable at startup and mutable at runtime. - On verify, pass the caller IP (
ip
) so the plugin can evaluate. - Behavior is the same as the static variant with the addition of runtime management helpers.
Settings
Option | Type | Default | Description |
---|---|---|---|
allow | string[] | [] | Initial whitelist of allowed IPs. If non-empty, only these are permitted. |
deny | string[] | [] | Initial blacklist of denied IPs. Deny takes precedence. |
Usage
import { usefulkey } from "betterkey";
import { ipAccessControlMemory, ipAccessControlStatic } from "usefulkey/plugins";
const uk = usefulkey({}, { plugins: [ipAccessControlMemory()] });
// Manage lists at runtime
uk.ipAccessControl.addAllow("127.0.0.1");
uk.ipAccessControl.addDeny("10.0.0.1");
const allow = uk.ipAccessControl.getAllow();
const deny = uk.ipAccessControl.getDeny();
// On verify, provide the caller IP
const res = await uk.verifyKey({ key, ip: "127.0.0.1" });
Functions added
The plugin extends your uk
instance with uk.ipAccessControl
methods:
addAllow(ip: string): void
removeAllow(ip: string): void
clearAllow(): void
addDeny(ip: string): void
removeDeny(ip: string): void
clearDeny(): void
getAllow(): string[]
getDeny(): string[]
Verification behavior
- Deny list match →
{ valid: false, reason: "ip_denied" }
- Allow list present and no match →
{ valid: false, reason: "ip_not_allowed" }
Emitted analytics on block: "ip_access.blocked"
with { ip, rule: "deny" | "allow_list_missing", plugin: "ip-access-control:memory", ts }
.
Using with Static IP Access Control
You can enable the static and memory variants at the same time. Both plugins run on each verification and the decision is combined:
- Deny lists are a union: if the IP appears in any plugin's
deny
, it is blocked. - Allow lists act as an intersection: if any plugin has a non-empty
allow
, the IP must be present in all suchallow
lists. - Order does not change the outcome. It only affects which plugin logs the block event.
import { usefulkey } from "betterkey";
const uk = usefulkey({}, {
plugins: [
ipAccessControlStatic({ allow: ["1.2.3.4"], deny: ["9.9.9.9"] }),
ipAccessControlMemory({ allow: ["1.2.3.4", "2.2.2.2"] }),
],
});
// On verify, provide the caller IP
await uk.verifyKey({ key, ip: "1.2.3.4" });