Skip to main content

Security Features

This document describes all security features implemented in the Identity Service.

Authentication Security

Token-Based Authentication

The Identity Service uses Laravel Sanctum for token-based authentication:

  • Bearer tokens sent via Authorization header
  • Token hashing - Tokens are stored as hashes in the database
  • Token expiration - Default 24 hours, extended to 30 days with "remember me"
  • Single token invalidation on logout

Password Security

Password Requirements

All passwords must meet these requirements:

RequirementDescription
Minimum length12 characters
UppercaseAt least one uppercase letter (A-Z)
LowercaseAt least one lowercase letter (a-z)
NumbersAt least one digit (0-9)
Special charactersAt least one special character (!@#$%^&*)

Password History

  • Last 5 passwords are stored (hashed)
  • Users cannot reuse any of their last 5 passwords
  • History is updated on every password change

Password Hashing

  • Algorithm: bcrypt
  • Cost factor: 12 (configurable)
  • Passwords are never stored in plain text

Force Password Change

Administrators can force users to change their password:

  • On first login
  • After a security incident
  • As part of regular rotation policy

Brute Force Protection

Rate Limiting

EndpointLimitWindow
Login5 attempts1 minute
Forgot Password5 attempts1 hour
2FA Verify5 attempts1 minute
PIN Verify5 attempts1 minute

After exceeding the limit, requests receive HTTP 429 (Too Many Requests).

Account Lockout

After 5 failed login attempts:

  • Account is temporarily locked for 15 minutes
  • User receives email notification
  • Failed attempts are logged

IP-Based Throttling

  • Rate limits are applied per IP address
  • Prevents distributed attacks from single source

Two-Factor Authentication (2FA)

TOTP Implementation

  • Algorithm: TOTP (Time-based One-Time Password)
  • Standard: RFC 6238
  • Code length: 6 digits
  • Time step: 30 seconds
  • Hash algorithm: SHA-1 (compatible with Google Authenticator)

2FA Secret Storage

Secret → encrypt() → Database
  • Secrets are encrypted using Laravel's encryption (AES-256-CBC)
  • Decrypted only when generating/verifying codes
  • Never exposed in API responses (except during setup)

Recovery Codes

  • 8 recovery codes generated on 2FA enable
  • Each code is single use
  • Codes are stored hashed
  • Regeneration invalidates all previous codes

2FA Flow

┌─────────────┐     ┌─────────────┐     ┌─────────────┐
│ Login │────▶│ 2FA Check │────▶│ 2FA Verify │
│ (email/pw) │ │ (has 2FA?) │ │ (TOTP) │
└─────────────┘ └─────────────┘ └─────────────┘
│ │
▼ ▼
No 2FA: Grant Verified: Grant
Full Access Full Access

Security PIN

PIN Requirements

RequirementDescription
LengthExactly 6 digits
No sequencesCannot be 123456, 654321, etc.
No repetitionCannot be 000000, 111111, etc.

PIN Storage

PIN → Hash::make() → Database
  • PINs are hashed using bcrypt
  • Same security as password hashing
  • Cannot be recovered, only reset

PIN Lockout

After 5 failed PIN attempts:

  • PIN is locked for 15 minutes
  • Notification sent to user
  • Requires password to unlock early

Session Security

Token Management

  • Each login creates a new token
  • Tokens are invalidated on logout
  • "Logout all devices" invalidates all user tokens

Session Tracking

For each session, we track:

  • Device information (browser, OS)
  • IP address
  • Last activity time
  • Created timestamp

Trusted Devices

  • Users can trust devices for 30 days
  • Trusted devices skip 2FA verification
  • Devices can be revoked at any time

Multi-Tenant Security

Tenant Isolation

-- Every user query includes tenant_id
SELECT * FROM users
WHERE tenant_id = ? AND id = ?
  • All data is scoped to tenant_id
  • Cross-tenant access is impossible at the database level
  • UUID-based IDs prevent ID enumeration

Tenant Validation

  • Tenant ID is extracted from authenticated user
  • Cannot be overridden via request parameters
  • All operations validate tenant ownership

Input Validation & Sanitization

Email Validation

  • RFC-compliant email validation
  • Case-insensitive storage (lowercase)
  • Duplicate prevention per tenant

XSS Prevention

  • All input is validated before processing
  • Output is escaped in API responses
  • Content-Type headers enforce JSON

SQL Injection Prevention

  • Eloquent ORM with prepared statements
  • No raw SQL queries with user input
  • Parameter binding for all queries

Audit Logging

Logged Events

EventDescription
user.loginSuccessful login
user.login_failedFailed login attempt
user.logoutUser logout
user.password_changedPassword change
user.profile_updatedProfile update
2fa.enabled2FA enabled
2fa.disabled2FA disabled
2fa.verified2FA code verified
2fa.failed2FA verification failed
pin.setPIN created
pin.changedPIN changed
pin.verifiedPIN verified
pin.failedPIN verification failed
device.addedNew device trusted
device.revokedDevice revoked

Log Data

Each log entry includes:

{
"id": "uuid",
"user_id": "uuid",
"tenant_id": "uuid",
"action": "user.login",
"ip_address": "192.168.1.1",
"user_agent": "Mozilla/5.0...",
"metadata": {},
"created_at": "2026-01-29T10:00:00.000Z"
}

Log Retention

  • Audit logs are retained for 365 days
  • Configurable per tenant
  • Exportable for compliance

API Security

CORS Configuration

'allowed_origins' => [
'https://identity.vecton.hu',
'https://*.vecton.hu',
],
'allowed_methods' => ['GET', 'POST', 'PUT', 'DELETE'],
'allowed_headers' => ['Authorization', 'Content-Type'],
'max_age' => 7200,

Security Headers

HeaderValue
X-Content-Type-Optionsnosniff
X-Frame-OptionsDENY
X-XSS-Protection1; mode=block
Strict-Transport-Securitymax-age=31536000
Content-Security-Policydefault-src 'self'

Request Validation

  • All requests are validated against defined rules
  • Invalid requests receive 422 with error details
  • Validation errors never expose sensitive data

Cryptographic Security

Encryption

  • Algorithm: AES-256-CBC
  • Key: APP_KEY (base64 encoded)
  • Used for: 2FA secrets, sensitive data

Hashing

  • Algorithm: bcrypt
  • Cost factor: 12
  • Used for: passwords, PINs, tokens

Random Generation

  • CSPRNG: random_bytes() / Str::random()
  • Used for: tokens, recovery codes, device IDs

Security Best Practices

For Users

  1. ✅ Use strong, unique passwords
  2. ✅ Enable 2FA
  3. ✅ Set up a security PIN
  4. ✅ Review active devices regularly
  5. ✅ Check activity logs for suspicious activity
  6. ✅ Don't share credentials

For Developers

  1. ✅ Never log sensitive data
  2. ✅ Use prepared statements
  3. ✅ Validate all input
  4. ✅ Use HTTPS only
  5. ✅ Keep dependencies updated
  6. ✅ Follow OWASP guidelines

For Administrators

  1. ✅ Enforce password policies
  2. ✅ Require 2FA for sensitive roles
  3. ✅ Review audit logs regularly
  4. ✅ Rotate API keys periodically
  5. ✅ Monitor for anomalies
  6. ✅ Have incident response plan

Compliance

GDPR Considerations

  • User data can be exported
  • User data can be deleted (right to be forgotten)
  • Consent is tracked
  • Data minimization principles applied

Security Standards

The Identity Service is designed following:

  • OWASP Top 10 - Security best practices
  • NIST 800-63B - Digital identity guidelines
  • ISO 27001 - Information security management

Incident Response

Security Incident Procedure

  1. Detect - Anomaly detection, user reports
  2. Assess - Determine scope and impact
  3. Contain - Lock affected accounts
  4. Eradicate - Remove threat
  5. Recover - Restore normal operation
  6. Learn - Post-incident review

Emergency Contacts