Security & Authorization Functions
Manage secure credentials and enforce role-based access control within your formulas.
$.secure.get()
Retrieve encrypted credentials from secure storage.
Syntax
$.secure.get(credentialKey)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
credentialKey | string | Yes | The key/name of the credential to retrieve |
Returns
Returns the decrypted credential value as a string, or null if not found.
Examples
Retrieve API Key
var apiKey = $.secure.get('PAYMENT_GATEWAY_API_KEY');
if (apiKey) {
var response = callExternalAPI(apiKey);
return response;
} else {
throw new Error('Payment gateway credentials not configured');
}
Multiple Credentials
var username = $.secure.get('EXTERNAL_SERVICE_USERNAME');
var password = $.secure.get('EXTERNAL_SERVICE_PASSWORD');
var authHeader = base64Encode(username + ':' + password);
// Use in API call
var result = doCmd('CallExternalAPI', {
url: 'https://api.example.com/endpoint',
headers: {
Authorization: 'Basic ' + authHeader
}
});
Conditional Access
var secretKey = $.secure.get('ENCRYPTION_KEY');
if (!secretKey) {
return {
success: false,
error: 'Encryption key not configured. Contact administrator.'
};
}
var encryptedData = encryptData(context.sensitiveData, secretKey);
return encryptedData;
Security Notes
- Credentials are stored encrypted in the database
- Credentials are decrypted on-demand when accessed
- Access is logged with user context for audit trails
- Never log or return secure credentials in responses
- Use secure credentials only within server-side formulas
Best Practices
// ✅ Good: Use credential, don't expose it
var apiKey = $.secure.get('API_KEY');
var response = callAPI(apiKey);
return { status: response.status };
// ❌ Bad: Don't return the credential
var apiKey = $.secure.get('API_KEY');
return { apiKey: apiKey }; // Security risk!
hasRole()
Check if the current user has a specific role.
Syntax
hasRole(roleName)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
roleName | string | Yes | Name of the role to check |
Returns
Returns true if the user has the role, false otherwise.
Examples
Conditional Logic Based on Role
if (hasRole('Teller')) {
// Allow teller operations
return doCmd('OpenTellerTill', context);
} else if (hasRole('Manager')) {
// Allow manager operations
return doCmd('ApproveLargeTransaction', context);
} else {
return {
success: false,
message: 'Insufficient permissions'
};
}
Show Different Data by Role
var transactions = doCmd('GetTransactions', {
accountNumber: context.accountNumber
});
if (hasRole('Admin') || hasRole('Auditor')) {
// Show full transaction details including system fields
return transactions;
} else {
// Show limited transaction details
return transactions.map(function(t) {
return {
date: t.date,
amount: t.amount,
description: t.description
};
});
}
Role-Based Limits
var maxAmount = 10000; // Default limit
if (hasRole('Manager')) {
maxAmount = 50000;
} else if (hasRole('Director')) {
maxAmount = 100000;
}
if (context.amount > maxAmount) {
return {
success: false,
message: 'Amount exceeds your authorization limit of ' + maxAmount
};
}
return doCmd('ProcessTransaction', context);
requireRole()
Require a specific role or throw an unauthorized exception.
Syntax
requireRole(roleName)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
roleName | string | Yes | Name of the required role |
Returns
No return value. Throws UnauthorizedAccessException if user lacks the role.
Examples
Protect Sensitive Operations
// Only managers can close accounts
requireRole('Manager');
var result = doCmd('CloseDepositAccount', {
accountNumber: context.accountNumber,
reason: context.reason
});
return result;
Enforce Business Rules
// Large withdrawals require approval role
if (context.amount > 50000) {
requireRole('TransactionApprover');
}
var result = doCmd('DebitDepositAccount', {
accountNumber: context.accountNumber,
amount: context.amount
});
return result;
Early Validation
// Check authorization first before expensive operations
requireRole('LoanOfficer');
// Expensive operations here - only execute if authorized
var creditCheck = doCmd('RunCreditCheck', context);
var loanEligibility = calculateLoanEligibility(creditCheck);
return loanEligibility;
hasClaim()
Check if the current user has a specific claim with a specific value.
Syntax
hasClaim(claimType, claimValue)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
claimType | string | Yes | Type/name of the claim |
claimValue | string | Yes | Expected value of the claim |
Returns
Returns true if the user has the claim with the specified value, false otherwise.
Examples
Check Branch Access
if (hasClaim('BranchId', context.branchId)) {
// User has access to this branch
return doCmd('ViewBranchTransactions', {
branchId: context.branchId
});
} else {
return {
success: false,
message: 'You do not have access to this branch'
};
}
Check Department Permissions
if (hasClaim('Department', 'Loans')) {
// Show loan-specific dashboard
return getLoanDashboard();
} else if (hasClaim('Department', 'Deposits')) {
// Show deposits-specific dashboard
return getDepositsDashboard();
} else {
// Show general dashboard
return getGeneralDashboard();
}
requireClaim()
Require a specific claim with a specific value or throw an unauthorized exception.
Syntax
requireClaim(claimType, claimValue)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
claimType | string | Yes | Type/name of the claim |
claimValue | string | Yes | Required value of the claim |
Returns
No return value. Throws UnauthorizedAccessException if user lacks the claim.
Examples
Enforce Regional Access
// Only users with West region claim can access
requireClaim('Region', 'West');
var result = doCmd('GetRegionalReport', {
region: 'West'
});
return result;
Department-Specific Operations
// Only compliance department can run this report
requireClaim('Department', 'Compliance');
var report = doCmd('GenerateComplianceReport', {
startDate: context.startDate,
endDate: context.endDate
});
return report;
requireAdmin()
Require the user to have the Admin role.
Syntax
requireAdmin()
Parameters
No parameters.
Returns
No return value. Throws UnauthorizedAccessException if user is not an admin.
Examples
Protect Admin Operations
requireAdmin();
// Only admins can execute system configuration
var result = doCmd('UpdateSystemConfiguration', {
key: context.key,
value: context.value
});
return result;
Admin-Only Reports
requireAdmin();
// Generate sensitive audit report
var report = {
userActivities: doCmd('GetUserActivityLog', {}),
systemChanges: doCmd('GetSystemChangeLog', {}),
securityEvents: doCmd('GetSecurityEvents', {})
};
return report;
requireAnyRole()
Require the user to have at least one of the specified roles.
Syntax
requireAnyRole(rolesArray)
Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
rolesArray | string[] | Yes | Array of role names (at least one required) |
Returns
No return value. Throws UnauthorizedAccessException if user has none of the roles.
Examples
Multiple Role Options
// Allow Managers or Directors to approve
requireAnyRole(['Manager', 'Director', 'CEO']);
var result = doCmd('ApproveLoanApplication', {
loanId: context.loanId,
approvalAmount: context.amount
});
return result;
Flexible Access Control
// Tellers, Supervisors, or Managers can process transactions
requireAnyRole(['Teller', 'Supervisor', 'Manager']);
var transaction = doCmd('ProcessDepositTransaction', {
accountNumber: context.accountNumber,
amount: context.amount
});
return transaction;
Tiered Authorization
// Different operations based on role tier
if (context.amount > 100000) {
requireAnyRole(['Director', 'CEO']);
} else if (context.amount > 50000) {
requireAnyRole(['Manager', 'Director', 'CEO']);
} else {
requireAnyRole(['Teller', 'Manager', 'Director', 'CEO']);
}
return doCmd('ProcessPayment', context);
getUserRoles()
Returns the authenticated user's distinct role claim values. The function reads
both the standard .NET role claim type and claims whose type is exactly role.
var roles = getUserRoles();
var isApprover = roles.indexOf('LoanApprover') >= 0;
The result is a string[]. An unauthenticated identity normally returns an
empty array.
getUserClaims()
Returns all claims for the current identity as objects containing type and
value.
var claims = getUserClaims();
return claims.map(function (claim) {
return {
type: claim.type,
value: claim.value
};
});
Claim values may contain identity or authorization information. Do not write the entire result to application logs or return it to untrusted clients.
getUserClaimsByType()
Returns the distinct values for an exact, case-sensitive claim type.
var permissions = getUserClaimsByType('Permission');
if (permissions.indexOf('APPROVE_LOAN') < 0) {
throw new Error('APPROVE_LOAN permission is required');
}
| Parameter | Type | Required | Description |
|---|---|---|---|
type | string | Yes | Exact claim type to retrieve. |
Complete Authorization Example
Multi-Level Access Control
// Check basic authentication
if (!hasRole('BankStaff')) {
return {
success: false,
error: 'Only bank staff can access this operation'
};
}
// Check amount-based authorization
var amount = context.amount;
if (amount > 100000) {
requireAnyRole(['Director', 'CEO']);
} else if (amount > 50000) {
requireAnyRole(['Manager', 'Director', 'CEO']);
} else if (amount > 10000) {
requireAnyRole(['Supervisor', 'Manager', 'Director', 'CEO']);
}
// Check branch access
requireClaim('BranchId', context.branchId);
// Get API credentials
var apiKey = $.secure.get('PAYMENT_PROCESSOR_KEY');
if (!apiKey) {
return {
success: false,
error: 'Payment processor not configured'
};
}
// Execute the operation
var result = doCmd('ProcessLargeTransaction', {
accountNumber: context.accountNumber,
amount: amount,
apiKey: apiKey
});
return {
success: true,
transactionId: result.transactionId,
message: 'Transaction processed successfully'
};
Error Handling
All authorization functions throw UnauthorizedAccessException when requirements are not met.
try {
requireRole('Manager');
var result = doCmd('SensitiveOperation', context);
return result;
} catch (error) {
if (error.name === 'UnauthorizedAccessException') {
return {
success: false,
error: 'You do not have permission to perform this operation',
requiredRole: 'Manager'
};
}
throw error; // Re-throw other errors
}
Best Practices
✅ Do
- Check authorization early in your formula
- Use
require*functions for mandatory checks - Use
has*functions for conditional logic - Combine role and claim checks for fine-grained control
- Never expose secure credentials in responses or logs
❌ Don't
- Don't hardcode credentials in formulas
- Don't return secure values to clients
- Don't skip authorization checks for "trusted" users
- Don't log sensitive security information
Common Patterns
Pattern 1: Tiered Authorization
var tier = hasRole('Admin') ? 'admin' :
hasRole('Manager') ? 'manager' :
hasRole('Teller') ? 'teller' : 'none';
switch (tier) {
case 'admin':
return getAdminView();
case 'manager':
return getManagerView();
case 'teller':
return getTellerView();
default:
throw new Error('Unauthorized');
}
Pattern 2: Feature Flags with Roles
var features = {
canApproveLoans: hasRole('LoanOfficer') || hasRole('Manager'),
canViewReports: hasRole('Manager') || hasRole('Auditor'),
canManageUsers: hasRole('Admin'),
canProcessPayments: hasRole('Teller') || hasRole('Manager')
};
return {
availableFeatures: features
};
Pattern 3: Secure External API Call
var apiKey = $.secure.get('EXTERNAL_API_KEY');
var apiSecret = $.secure.get('EXTERNAL_API_SECRET');
if (!apiKey || !apiSecret) {
throw new Error('API credentials not configured');
}
var signature = hmacSha256(apiSecret, context.requestData);
var response = doCmd('CallExternalAPI', {
url: 'https://api.external.com/endpoint',
headers: {
'X-API-Key': apiKey,
'X-Signature': signature
},
body: context.requestData
});
// Return only non-sensitive data
return {
status: response.status,
data: response.data
};