AuthSubject
The AuthSubject is the identity being evaluated against a policy. It carries the subject's permissions, roles, and attributes.
AuthSubject Interface
type AuthSubject = {
readonly id: string;
readonly permissions: ReadonlySet<Permission>;
readonly roles: ReadonlySet<Role>;
readonly attributes: Readonly<Record<string, unknown>>;
};
id-- unique identifier for the subject (user ID, service account ID, etc.)permissions-- the set of permissions the subject holdsroles-- the set of roles assigned to the subjectattributes-- arbitrary key-value pairs for attribute-based policies
SubjectProviderPort
A scoped port for resolving the current subject in DI contexts. The subject provider is typically scoped per-request or per-session.
import { SubjectProviderPort } from "@hex-di/guard";
// Adapter that resolves the current user from a request context
const RequestSubjectAdapter = createAdapter(SubjectProviderPort, {
factory: ({ requestContext }) => ({
getSubject: () => requestContext.currentUser,
}),
ports: [RequestContextPort],
});
createAuthSubject()
Factory function for creating AuthSubject instances.
import { createAuthSubject } from "@hex-di/guard";
const subject = createAuthSubject({
id: "user-1",
permissions: [ReadUsers, WriteUsers],
roles: [EditorRole],
attributes: {
department: "engineering",
status: "active",
},
});
The factory converts permission and role arrays to ReadonlySet internally.
withAttributes()
Creates a new subject with additional or overridden attributes. Does not mutate the original.
import { withAttributes } from "@hex-di/guard";
const enriched = withAttributes(subject, {
lastLogin: new Date(),
mfaVerified: true,
});
// enriched has all original attributes plus lastLogin and mfaVerified
getAttribute()
Type-safe attribute retrieval.
import { getAttribute } from "@hex-di/guard";
const department = getAttribute(subject, "department");
// department: unknown -- use type guards for specific types
PrecomputedSubject
For hot paths where permission/role lookups need to be O(1), PrecomputedSubject precomputes flattened permission sets from roles at construction time.
import { PrecomputedSubject } from "@hex-di/guard";
const precomputed = PrecomputedSubject.from(subject);
// All role permissions are flattened into the permission set
// hasPermission checks are O(1) Set lookups
This is an optimization -- the standard AuthSubject works for most cases. Use PrecomputedSubject when you're evaluating many policies against the same subject (e.g., batch authorization checks).