Delegation Validation
Validating scope and constraints in delegation credentials
Scope and Constraint Validation
After validating the credential's integrity, the verifier must check if the requested action is authorized.
Scope Validation
- Extract the delegated scopes from the credential
- Compare the requested action against the delegated scopes
- Ensure the requested action is fully covered by at least one delegated scope
function validateScope(credential, requestedAction, requestedResource) {
const scopes = credential.credentialSubject.scope;
// Check if any scope covers the requested action and resource
return scopes.some((scope) => {
// Parse scope into action and resource
const [scopeAction, scopeResource] = scope.split(":");
// Check if scope action matches or is wildcard
const actionMatch = scopeAction === "*" || scopeAction === requestedAction;
// Check if scope resource matches or is wildcard
const resourceMatch =
scopeResource === "*" ||
scopeResource === requestedResource ||
requestedResource.startsWith(`${scopeResource}/`);
return actionMatch && resourceMatch;
});
}
Constraint Validation
For credentials with additional constraints:
- Extract constraint expressions from the credential
- Evaluate constraints against the current context
- Only proceed if all constraints are satisfied
function validateConstraints(credential, context) {
const constraints = credential.credentialSubject.constraints;
if (!constraints) return true;
// Check environment constraint
if (
constraints.environment &&
constraints.environment !== context.environment
) {
return false;
}
// Check time window constraint
if (constraints.timeWindow) {
const now = new Date();
const dayOfWeek = now.getDay();
const hourOfDay = now.getHours();
if (!constraints.timeWindow.daysOfWeek.includes(dayOfWeek)) {
return false;
}
if (
hourOfDay < constraints.timeWindow.hoursOfDay[0] ||
hourOfDay > constraints.timeWindow.hoursOfDay[1]
) {
return false;
}
}
// Check geo constraint if present
if (constraints.geoFence && context.location) {
if (!isPointInPolygon(context.location, constraints.geoFence)) {
return false;
}
}
return true;
}