Instruction file imported from Xala-Technologies/xala-enterprise (
.cursor/rules/compliance-security.mdc). Copyright stays with the author.
Compliance & Security Standards
🎯 COMPLIANCE MANDATE
MANDATORY compliance with Norwegian and international standards for security, accessibility, privacy, and digital governance.
🇳🇴 NORWEGIAN COMPLIANCE REQUIREMENTS
1. NSM (Nasjonal sikkerhetsmyndighet) - National Security Authority
// REQUIRED - Security classification and handling
export interface SecurityClassification {
level: 'ÅPEN' | 'BEGRENSET' | 'KONFIDENSIELT' | 'HEMMELIG';
handling: string[];
retention: string;
destruction: string;
}
// MANDATORY - Data classification for all entities
@Entity('users')
export class UserEntity {
@Column({ type: 'jsonb' })
@SecurityClassified('BEGRENSET') // Personal data classification
personalData: PersonalDataFields;
@Column({ type: 'jsonb' })
@SecurityClassified('ÅPEN') // Public data classification
publicProfile: PublicProfileFields;
}
NSM Security Requirements:
- MANDATORY data classification for all information assets
- REQUIRED encryption at rest and in transit (AES-256, TLS 1.3)
- FORBIDDEN storing classified data without proper security controls
- MANDATORY audit logging for all data access and modifications
- REQUIRED incident response procedures and breach notification
2. DigDir (Digitaliseringsdirektoratet) Standards
// REQUIRED - Digital service standards compliance
export interface DigitalServiceStandards {
accessibility: 'WCAG_2_2_AA';
security: 'NSM_BASIC' | 'NSM_HIGH';
privacy: 'GDPR_COMPLIANT';
interoperability: 'FHIR_R4' | 'REST_API';
authentication: 'ID_PORTEN' | 'ALTINN';
}
// MANDATORY - Service registration and metadata
@Injectable()
export class ServiceRegistryService {
async registerService(service: DigitalServiceMetadata): Promise<void> {
// Register with DigDir service catalog
await this.digdirClient.registerService({
...service,
compliance: {
accessibility: 'WCAG_2_2_AA',
security: 'NSM_BASIC',
privacy: 'GDPR_COMPLIANT'
}
});
}
}
DigDir Requirements:
- MANDATORY WCAG 2.2 AA accessibility compliance
- REQUIRED integration with ID-porten for citizen authentication
- MANDATORY service registration in national service catalog
- REQUIRED API documentation following OpenAPI 3.0 standards
- MANDATORY Norwegian language support (Bokmål/Nynorsk)
🔒 ISO 27001 INFORMATION SECURITY
1. Information Security Management System (ISMS)
// REQUIRED - Security controls implementation
export class SecurityControlsService {
// A.8.2.1 - Classification of information
@SecurityControl('A.8.2.1')
async classifyInformation(data: any): Promise<SecurityClassification> {
return this.classificationEngine.classify(data);
}
// A.9.1.1 - Access control policy
@SecurityControl('A.9.1.1')
async enforceAccessControl(user: User, resource: Resource): Promise<boolean> {
return this.rbacService.checkAccess(user, resource);
}
// A.12.6.1 - Management of technical vulnerabilities
@SecurityControl('A.12.6.1')
async scanVulnerabilities(): Promise<VulnerabilityReport> {
return this.vulnerabilityScanner.scan();
}
}
ISO 27001 Security Controls:
- A.5 - Information Security Policies
- A.6 - Organization of Information Security
- A.7 - Human Resource Security
- A.8 - Asset Management
- A.9 - Access Control
- A.10 - Cryptography
- A.11 - Physical and Environmental Security
- A.12 - Operations Security
- A.13 - Communications Security
- A.14 - System Acquisition, Development and Maintenance
- A.15 - Supplier Relationships
- A.16 - Information Security Incident Management
- A.17 - Information Security Aspects of Business Continuity Management
- A.18 - Compliance
2. Risk Management
// MANDATORY - Risk assessment and treatment
export interface SecurityRisk {
id: string;
asset: string;
threat: string;
vulnerability: string;
likelihood: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
impact: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
riskLevel: number;
treatment: 'ACCEPT' | 'MITIGATE' | 'TRANSFER' | 'AVOID';
controls: SecurityControl[];
}
@Injectable()
export class RiskManagementService {
async assessRisk(asset: Asset): Promise<SecurityRisk[]> {
return this.riskEngine.assess(asset);
}
async implementControls(risk: SecurityRisk): Promise<void> {
await this.controlImplementation.deploy(risk.controls);
}
}
♿ ACCESSIBILITY COMPLIANCE (WCAG 2.2 AA)
1. Universal Design (Universal Utforming)
// REQUIRED - Accessibility implementation
export interface AccessibilityStandards {
wcag: '2.2';
level: 'AA';
universalDesign: true;
screenReaderSupport: true;
keyboardNavigation: true;
colorContrastRatio: number; // Minimum 4.5:1
}
// MANDATORY - Accessible component patterns
@Component({
selector: 'accessible-button',
template: `
<button
[attr.aria-label]="ariaLabel"
[attr.aria-describedby]="ariaDescribedBy"
[attr.aria-pressed]="pressed"
[disabled]="disabled"
(click)="onClick()"
(keydown.enter)="onClick()"
(keydown.space)="onClick()"
class="accessible-button"
>
<ng-content></ng-content>
</button>
`
})
export class AccessibleButtonComponent {
@Input() ariaLabel: string;
@Input() ariaDescribedBy: string;
@Input() pressed: boolean;
@Input() disabled: boolean;
}
WCAG 2.2 AA Requirements:
- 1.1 - Text Alternatives
- 1.2 - Time-based Media
- 1.3 - Adaptable
- 1.4 - Distinguishable
- 2.1 - Keyboard Accessible
- 2.2 - Enough Time
- 2.3 - Seizures and Physical Reactions
- 2.4 - Navigable
- 2.5 - Input Modalities
- 3.1 - Readable
- 3.2 - Predictable
- 3.3 - Input Assistance
- 4.1 - Compatible
2. Accessibility Testing
// REQUIRED - Automated accessibility testing
describe('Accessibility Compliance', () => {
it('should meet WCAG 2.2 AA standards', async () => {
const results = await axe.run(document, {
tags: ['wcag22aa'],
rules: {
'color-contrast': { enabled: true },
'keyboard-navigation': { enabled: true },
'screen-reader': { enabled: true }
}
});
expect(results.violations).toHaveLength(0);
});
it('should support keyboard navigation', async () => {
const focusableElements = getFocusableElements(document);
expect(focusableElements.length).toBeGreaterThan(0);
// Test tab order
for (let i = 0; i < focusableElements.length; i++) {
expect(focusableElements[i]).toHaveAttribute('tabindex');
}
});
});
🛡️ GDPR COMPLIANCE
1. Data Protection by Design and Default
// REQUIRED - GDPR compliance implementation
export interface GDPRCompliance {
lawfulBasis: 'CONSENT' | 'CONTRACT' | 'LEGAL_OBLIGATION' | 'VITAL_INTERESTS' | 'PUBLIC_TASK' | 'LEGITIMATE_INTERESTS';
dataMinimization: boolean;
purposeLimitation: string[];
storageTime: string;
dataSubjectRights: DataSubjectRights;
}
export interface DataSubjectRights {
rightToAccess: boolean;
rightToRectification: boolean;
rightToErasure: boolean;
rightToRestriction: boolean;
rightToPortability: boolean;
rightToObject: boolean;
}
// MANDATORY - Personal data handling
@Entity('personal_data')
export class PersonalDataEntity {
@Column()
@GDPRField({
category: 'PERSONAL',
lawfulBasis: 'CONSENT',
retention: 'P2Y' // ISO 8601 duration
})
email: string;
@Column({ type: 'jsonb' })
@GDPRField({
category: 'SENSITIVE',
lawfulBasis: 'EXPLICIT_CONSENT',
retention: 'P1Y'
})
healthData?: HealthInformation;
@Column()
@Encrypted()
@GDPRField({
category: 'PERSONAL',
lawfulBasis: 'CONTRACT',
retention: 'P7Y'
})
nationalId: string;
}
2. Data Subject Rights Implementation
// REQUIRED - GDPR rights implementation
@Injectable()
export class GDPRService {
// Article 15 - Right of access
async exportPersonalData(userId: string): Promise<PersonalDataExport> {
const userData = await this.userRepository.findWithAllData(userId);
return this.gdprExporter.createExport(userData);
}
// Article 16 - Right to rectification
async rectifyPersonalData(userId: string, corrections: DataCorrections): Promise<void> {
await this.userRepository.updatePersonalData(userId, corrections);
await this.auditLogger.logDataRectification(userId, corrections);
}
// Article 17 - Right to erasure (Right to be forgotten)
async erasePersonalData(userId: string, reason: ErasureReason): Promise<void> {
await this.dataErasureService.anonymizeUser(userId);
await this.auditLogger.logDataErasure(userId, reason);
}
// Article 20 - Right to data portability
async exportPortableData(userId: string, format: 'JSON' | 'XML' | 'CSV'): Promise<PortableDataExport> {
const data = await this.userRepository.findPortableData(userId);
return this.dataPortabilityService.export(data, format);
}
}
3. Consent Management
// MANDATORY - Consent tracking and management
export interface ConsentRecord {
id: string;
userId: string;
purpose: string;
lawfulBasis: string;
consentGiven: boolean;
consentWithdrawn: boolean;
timestamp: Date;
ipAddress: string;
userAgent: string;
method: 'EXPLICIT' | 'IMPLIED' | 'OPT_IN' | 'OPT_OUT';
}
@Injectable()
export class ConsentManagementService {
async recordConsent(consent: ConsentRecord): Promise<void> {
await this.consentRepository.save(consent);
await this.auditLogger.logConsentChange(consent);
}
async withdrawConsent(userId: string, purpose: string): Promise<void> {
await this.consentRepository.withdrawConsent(userId, purpose);
await this.dataProcessingService.stopProcessing(userId, purpose);
}
async getConsentStatus(userId: string): Promise<ConsentRecord[]> {
return this.consentRepository.findByUser(userId);
}
}
🔐 AUTHENTICATION & AUTHORIZATION
1. ID-porten Integration
// REQUIRED - Norwegian national authentication
export interface IDPortenConfig {
clientId: string;
clientSecret: string;
redirectUri: string;
scopes: string[];
acr: 'Level3' | 'Level4'; // Security level
}
@Injectable()
export class IDPortenService {
async authenticate(user: User): Promise<IDPortenToken> {
const authUrl = this.buildAuthUrl();
const token = await this.exchangeCodeForToken(authUrl);
// Validate security level
if (token.acr !== 'Level4') {
throw new SecurityException('Insufficient authentication level');
}
return token;
}
async validateToken(token: string): Promise<IDPortenClaims> {
const claims = await this.jwtService.verify(token);
await this.auditLogger.logAuthentication(claims.sub);
return claims;
}
}
2. Altinn Integration
// REQUIRED - Norwegian business authentication
export interface AltinnConfig {
apiKey: string;
environment: 'TT02' | 'PROD';
serviceCode: string;
serviceEdition: string;
}
@Injectable()
export class AltinnService {
async authorizeOrganization(orgNumber: string, user: User): Promise<boolean> {
const rights = await this.altinnClient.getRights(orgNumber, user.nationalId);
return rights.includes('READ') || rights.includes('WRITE');
}
async getOrganizationData(orgNumber: string): Promise<OrganizationData> {
return this.altinnClient.getOrganization(orgNumber);
}
}
📊 AUDIT & MONITORING
1. Security Event Logging
// MANDATORY - Comprehensive audit logging
export interface SecurityEvent {
id: string;
timestamp: Date;
eventType: 'AUTHENTICATION' | 'AUTHORIZATION' | 'DATA_ACCESS' | 'DATA_MODIFICATION' | 'SECURITY_INCIDENT';
severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
userId?: string;
ipAddress: string;
userAgent: string;
resource: string;
action: string;
outcome: 'SUCCESS' | 'FAILURE';
details: Record<string, any>;
}
@Injectable()
export class SecurityAuditService {
async logSecurityEvent(event: SecurityEvent): Promise<void> {
// Store in secure audit log
await this.auditRepository.save(event);
// Send to SIEM system
await this.siemIntegration.sendEvent(event);
// Alert on critical events
if (event.severity === 'CRITICAL') {
await this.alertService.sendCriticalAlert(event);
}
}
async generateAuditReport(period: DateRange): Promise<AuditReport> {
const events = await this.auditRepository.findByDateRange(period);
return this.reportGenerator.createAuditReport(events);
}
}
2. Incident Response
// REQUIRED - Security incident handling
export interface SecurityIncident {
id: string;
type: 'DATA_BREACH' | 'UNAUTHORIZED_ACCESS' | 'MALWARE' | 'DDOS' | 'PHISHING';
severity: 'LOW' | 'MEDIUM' | 'HIGH' | 'CRITICAL';
status: 'DETECTED' | 'INVESTIGATING' | 'CONTAINED' | 'RESOLVED';
detectedAt: Date;
containedAt?: Date;
resolvedAt?: Date;
affectedSystems: string[];
affectedUsers: string[];
description: string;
response: IncidentResponse;
}
@Injectable()
export class IncidentResponseService {
async reportIncident(incident: SecurityIncident): Promise<void> {
await this.incidentRepository.save(incident);
// Notify authorities if required (72 hours for GDPR)
if (this.requiresAuthorityNotification(incident)) {
await this.notifyDataProtectionAuthority(incident);
}
// Notify affected users
if (incident.affectedUsers.length > 0) {
await this.notifyAffectedUsers(incident);
}
}
private requiresAuthorityNotification(incident: SecurityIncident): boolean {
return incident.type === 'DATA_BREACH' &&
incident.severity in ['HIGH', 'CRITICAL'];
}
}
🌐 INTERNATIONALIZATION & LOCALIZATION
1. Norwegian Language Support
// MANDATORY - Norwegian language compliance
export interface NorwegianLocalization {
bokmaal: boolean; // Bokmål support
nynorsk: boolean; // Nynorsk support
sami: boolean; // Sami language support
signLanguage: boolean; // Norwegian Sign Language
}
// REQUIRED - Official Norwegian terminology
export const NorwegianTerms = {
// Use official Norwegian terms from Språkrådet
'user': 'bruker',
'login': 'logg inn',
'password': 'passord',
'email': 'e-post',
'organization': 'organisasjon',
'municipality': 'kommune',
'county': 'fylke',
'nationalId': 'fødselsnummer'
} as const;
2. Cultural Adaptation
// REQUIRED - Norwegian cultural standards
export interface CulturalStandards {
dateFormat: 'DD.MM.YYYY'; // Norwegian date format
timeFormat: 'HH:mm'; // 24-hour format
currency: 'NOK'; // Norwegian Kroner
numberFormat: '1 234,56'; // Norwegian number format
addressFormat: NorwegianAddressFormat;
phoneFormat: '+47 XXX XX XXX';
}
export interface NorwegianAddressFormat {
streetAddress: string;
postalCode: string; // 4 digits
city: string;
municipality?: string;
county?: string;
}
🔍 COMPLIANCE MONITORING
1. Automated Compliance Checks
// REQUIRED - Continuous compliance monitoring
@Injectable()
export class ComplianceMonitoringService {
async runComplianceChecks(): Promise<ComplianceReport> {
const checks = await Promise.all([
this.checkWCAGCompliance(),
this.checkGDPRCompliance(),
this.checkSecurityCompliance(),
this.checkDataRetentionCompliance(),
this.checkAccessControlCompliance()
]);
return this.generateComplianceReport(checks);
}
private async checkWCAGCompliance(): Promise<ComplianceCheck> {
const violations = await this.accessibilityScanner.scan();
return {
standard: 'WCAG_2_2_AA',
compliant: violations.length === 0,
violations: violations
};
}
private async checkGDPRCompliance(): Promise<ComplianceCheck> {
const issues = await this.gdprAuditor.audit();
return {
standard: 'GDPR',
compliant: issues.length === 0,
violations: issues
};
}
}
2. Compliance Reporting
// MANDATORY - Regular compliance reporting
export interface ComplianceReport {
reportDate: Date;
period: DateRange;
standards: {
wcag: ComplianceStatus;
gdpr: ComplianceStatus;
iso27001: ComplianceStatus;
nsm: ComplianceStatus;
digdir: ComplianceStatus;
};
violations: ComplianceViolation[];
recommendations: string[];
nextAuditDate: Date;
}
@Injectable()
export class ComplianceReportingService {
async generateMonthlyReport(): Promise<ComplianceReport> {
const report = await this.complianceMonitoring.runComplianceChecks();
// Submit to authorities if required
await this.submitToAuthorities(report);
// Store for audit trail
await this.reportRepository.save(report);
return report;
}
}
📋 PRE-COMMIT COMPLIANCE CHECKLIST
Before committing any code:
- NSM Security: Data classified and encrypted appropriately
- DigDir Standards: Service metadata and accessibility validated
- ISO 27001: Security controls implemented and tested
- WCAG 2.2 AA: Accessibility standards met and tested
- Universal Design: Norwegian accessibility requirements fulfilled
- GDPR: Personal data handling compliant and documented
- ID-porten: Authentication integration tested
- Audit Logging: All security events properly logged
- Incident Response: Security incident procedures documented
- Norwegian Language: Proper localization implemented
- Compliance Monitoring: Automated checks passing
🎯 COMPLIANCE SUCCESS METRICS
Compliance is successful when:
- 100% WCAG 2.2 AA accessibility compliance
- Zero GDPR violations or data breaches
- Complete audit trail for all data access
- Certified ISO 27001 compliance
- Integrated with Norwegian national services (ID-porten, Altinn)
- Validated by Norwegian authorities (NSM, DigDir)
- Documented incident response procedures
- Automated compliance monitoring and reporting
- Multilingual support including Norwegian (Bokmål/Nynorsk)
- Cultural adaptation for Norwegian users and organizations
🚨 COMPLIANCE VIOLATIONS
ZERO TOLERANCE for:
- Accessibility barriers preventing universal access
- Personal data processing without lawful basis
- Security incidents without proper notification
- Missing audit trails for sensitive operations
- Non-compliance with Norwegian digital standards
- Inadequate encryption or data protection
- Unauthorized access to classified information
- Missing consent for personal data processing