@yugami/trust
v0.1.1
Published
Framework-agnostic trust engine for the Yugami ecosystem.
Readme
@yugami/trust
Framework-agnostic trust engine for the Yugami ecosystem.
This package evaluates infrastructure trust at the edge or between private services. It is intentionally independent of Fastify, Express, Next.js, and business authorization logic.
What It Does
- Evaluates request trust deterministically
- Supports
public-edgeandprivate-servicemodes - Applies blocked IP, allowed IP, private CIDR, and allowed origin rules
- Exposes a framework-agnostic
createTrustGuard()factory - Includes a thin Fastify adapter for direct hook usage
- Returns a small auditable result object instead of throwing framework-specific responses
What It Does Not Do
- JWT verification
- RBAC or user roles
- Product authorization
- Business domain checks
- Framework middleware by default
Installation
Inside this monorepo, add it as a workspace dependency where needed:
{
"dependencies": {
"@yugami/trust": "workspace:*"
}
}API
import {
createTrustGuard,
evaluateTrust,
type TrustConfig,
type CreateTrustGuardOptions,
type TrustInput,
} from "@yugami/trust";Trust Modes
type TrustMode = "public-edge" | "private-service";Trust Input
type TrustInput = {
ip?: string;
origin?: string;
path?: string;
headers?: Record<string, string | undefined>;
mode: TrustMode;
};Trust Config
type TrustConfig = {
blockedIPs?: string[];
allowedIPs?: string[];
privateCIDRs?: string[];
allowedDomains?: string[];
};Trust Result
type TrustResult = {
allowed: boolean;
reason?:
| "blocked_ip"
| "origin_required"
| "origin_not_allowed"
| "private_access_denied"
| "invalid_request";
};Trust Guard Factory
type CreateTrustGuardOptions<TRequest = unknown> = {
mode: TrustMode;
config: TrustConfig;
getClientIp: (request: TRequest) => string | undefined;
getOrigin?: (request: TRequest) => string | undefined;
requireOrigin?: boolean | ((request: TRequest) => boolean);
skip?: (request: TRequest) => boolean;
onDeny?: (
result: TrustResult,
request: TRequest,
) => void | Promise<void>;
};Basic Example
import { evaluateTrust } from "@yugami/trust";
const result = evaluateTrust(
{
ip: "127.0.0.1",
origin: "https://identity.yugami.in",
path: "/identity/login",
mode: "public-edge",
},
{
blockedIPs: [],
allowedIPs: ["127.0.0.1", "::1"],
privateCIDRs: [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"100.64.0.0/10",
"127.0.0.1/32",
"::1/128",
"fc00::/7",
],
allowedDomains: [
"identity.yugami.in",
"identity.dev.yugami.in",
"studio.yugami.in",
"studio.dev.yugami.in",
],
},
);Recommended Config Pattern
Keep config in your app and pass it into thin framework middleware.
import type { TrustConfig } from "@yugami/trust";
export const TRUST_CONFIG: TrustConfig = {
blockedIPs: [],
allowedIPs: ["127.0.0.1", "::1"],
privateCIDRs: [
"10.0.0.0/8",
"172.16.0.0/12",
"192.168.0.0/16",
"100.64.0.0/10",
"127.0.0.1/32",
"::1/128",
"fc00::/7",
],
allowedDomains: [
"identity.yugami.in",
"identity.dev.yugami.in",
"studio.yugami.in",
"studio.dev.yugami.in",
],
};createTrustGuard()
This is the main production API for framework integration. It keeps policy in one place and returns a pure trust result.
import { createTrustGuard } from "@yugami/trust";
const trustGuard = createTrustGuard({
mode: "public-edge",
config: TRUST_CONFIG,
getClientIp: (request: { ip?: string }) => request.ip,
getOrigin: (request: { headers: Record<string, string | undefined> }) =>
request.headers.origin,
requireOrigin: (request: { url: string }) => request.url.startsWith("/auth"),
skip: (request: { url: string }) =>
request.url === "/health" || request.url === "/ready",
onDeny: async (result, request) => {
console.warn("trust denied", {
reason: result.reason,
request,
});
},
});Guard Behavior
public-edgevalidates blocked IPs first, then validates origin only when origin data is present or whenrequireOriginis enabled at the guard levelprivate-servicevalidates blocked IPs, allowed IPs, and private CIDRs, then skips origin validation by defaultskip()bypasses trust evaluation for infrastructure routes such as/healthand/metrics
Fastify Usage
For Fastify, the package now includes a thin adapter:
import Fastify from "fastify";
import { createFastifyTrustMiddleware } from "@yugami/trust";
import { TRUST_CONFIG } from "./config/trust";
const app = Fastify({
logger: true,
});
const trustMiddleware = createFastifyTrustMiddleware({
mode: "public-edge",
config: TRUST_CONFIG,
requireOrigin: (request) => request.url.startsWith("/auth"),
skip: (request) => request.url === "/health",
onDeny: async (result, request) => {
request.log.warn({
reason: result.reason,
ip: request.ip,
});
},
});
app.addHook("onRequest", trustMiddleware);If you want full control, you can still use createTrustGuard() directly inside a hook.
import Fastify, { FastifyReply, FastifyRequest } from "fastify";
import { createTrustGuard } from "@yugami/trust";
import { TRUST_CONFIG } from "./config/trust";
const trustGuard = createTrustGuard<FastifyRequest>({
mode: "private-service",
config: TRUST_CONFIG,
getClientIp: (request) => request.ip,
skip: (request) => request.url === "/health",
onDeny: async (result, request) => {
request.log.warn({
reason: result.reason,
ip: request.ip,
});
},
});
async function trustMiddleware(request: FastifyRequest, reply: FastifyReply) {
const result = await trustGuard(request);
if (!result.allowed) {
return reply.code(403).send({
error: "Access denied",
reason: result.reason,
});
}
}
const app = Fastify({
logger: true,
});
app.addHook("onRequest", trustMiddleware);Fastify Notes
- Use
mode: "public-edge"for internet-facing APIs where most traffic is allowed and blocked IP/origin rules are used for abuse prevention. - Use
mode: "private-service"for internal APIs that should only trust allowlisted IPs or private CIDR traffic. - Use
requireOriginonly for browser-facingpublic-edgeroutes such as auth, dashboard, or session endpoints. - If your app is behind a proxy or load balancer, make sure Fastify is configured so
request.ipreflects the correct client IP.
Express Usage
Express integration works best through createTrustGuard().
import express, { NextFunction, Request, Response } from "express";
import { createTrustGuard } from "@yugami/trust";
import { TRUST_CONFIG } from "./config/trust";
const app = express();
app.set("trust proxy", true);
const trustGuard = createTrustGuard<Request>({
mode: "public-edge",
config: TRUST_CONFIG,
getClientIp: (request) => request.ip,
getOrigin: (request) =>
typeof request.headers.origin === "string"
? request.headers.origin
: undefined,
requireOrigin: (request) =>
request.path.startsWith("/auth") || request.path.startsWith("/dashboard"),
skip: (request) => request.path === "/health",
});
async function trustMiddleware(req: Request, res: Response, next: NextFunction) {
const result = await trustGuard(req);
if (!result.allowed) {
return res.status(403).json({
error: "Access denied",
reason: result.reason,
});
}
next();
}
app.use(trustMiddleware);Express Notes
app.set("trust proxy", true)is often required when Express runs behind a reverse proxy, otherwisereq.ipmay not be what you expect.- Prefer validating proxy behavior carefully in production before relying on IP-based rules.
Mode Guidance
public-edge
Use for public APIs such as api.yugami.in.
- Public traffic is generally allowed
blockedIPscan deny abusive trafficallowedDomainscan enforce browser-origin restrictions when neededrequireOriginshould be enabled only for browser-facing routes that must not accept origin-less traffic
private-service
Use for internal APIs such as api-identity.yugami.in and api-sikshya.yugami.in.
- Only
allowedIPsor matchingprivateCIDRsare trusted - Origin is skipped by default after private network trust checks pass
- Missing or invalid IP input is denied
Response Handling
The package does not send responses itself. Your app decides what to do with the result.
Example:
const result = evaluateTrust(input, config);
if (!result.allowed) {
return {
statusCode: 403,
body: {
error: "Access denied",
reason: result.reason,
},
};
}Exports
import {
DEFAULT_TRUST_CONFIG,
createFastifyTrustMiddleware,
createTrustGuard,
evaluateTrust,
getOriginHostname,
isAllowedDomain,
isIpAllowed,
isIpBlocked,
isIpInCIDR,
isPrivateCIDR,
isValidIp,
} from "@yugami/trust";