opaque_id 1.2.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/.release-please-manifest.json +1 -1
- data/CHANGELOG.md +48 -0
- data/CODE_OF_CONDUCT.md +11 -11
- data/README.md +82 -0
- data/docs/.gitignore +5 -0
- data/docs/404.html +25 -0
- data/docs/Gemfile +31 -0
- data/docs/Gemfile.lock +335 -0
- data/docs/_config.yml +151 -0
- data/docs/_data/navigation.yml +132 -0
- data/docs/_includes/footer_custom.html +8 -0
- data/docs/_includes/head_custom.html +67 -0
- data/docs/algorithms.md +412 -0
- data/docs/alphabets.md +524 -0
- data/docs/api-reference.md +597 -0
- data/docs/assets/css/custom.scss +751 -0
- data/docs/assets/images/favicon.svg +17 -0
- data/docs/assets/images/og-image.svg +65 -0
- data/docs/configuration.md +551 -0
- data/docs/development.md +570 -0
- data/docs/getting-started.md +259 -0
- data/docs/index.md +135 -0
- data/docs/installation.md +380 -0
- data/docs/performance.md +491 -0
- data/docs/robots.txt +11 -0
- data/docs/security.md +601 -0
- data/docs/usage.md +417 -0
- data/docs/use-cases.md +572 -0
- data/lib/opaque_id/version.rb +1 -1
- data/tasks/0003-prd-documentation-site.md +191 -0
- data/tasks/tasks-0003-prd-documentation-site.md +84 -0
- metadata +27 -2
- data/sig/opaque_id.rbs +0 -4
data/docs/security.md
ADDED
@@ -0,0 +1,601 @@
|
|
1
|
+
---
|
2
|
+
layout: default
|
3
|
+
title: Security
|
4
|
+
nav_order: 9
|
5
|
+
description: "Security considerations, best practices, and threat model analysis"
|
6
|
+
permalink: /security/
|
7
|
+
---
|
8
|
+
|
9
|
+
# Security
|
10
|
+
|
11
|
+
OpaqueId is designed with security as a primary concern, providing cryptographically secure ID generation with protection against various attack vectors. This guide covers security considerations, best practices, and threat model analysis.
|
12
|
+
|
13
|
+
- TOC
|
14
|
+
{:toc}
|
15
|
+
|
16
|
+
## Cryptographic Security
|
17
|
+
|
18
|
+
### SecureRandom Foundation
|
19
|
+
|
20
|
+
OpaqueId is built on Ruby's `SecureRandom`, which provides cryptographically secure pseudo-random number generation.
|
21
|
+
|
22
|
+
```ruby
|
23
|
+
# OpaqueId uses SecureRandom for all random generation
|
24
|
+
def generate_secure_id
|
25
|
+
# Cryptographically secure random bytes
|
26
|
+
byte = SecureRandom.random_bytes(1).unpack1("C")
|
27
|
+
|
28
|
+
# No predictable patterns
|
29
|
+
# No timing attacks
|
30
|
+
# No statistical bias
|
31
|
+
end
|
32
|
+
```
|
33
|
+
|
34
|
+
**Security Properties:**
|
35
|
+
|
36
|
+
- **Cryptographically Secure**: Uses OS entropy sources
|
37
|
+
- **Unpredictable**: Cannot be predicted from previous outputs
|
38
|
+
- **High Entropy**: Sufficient randomness for security applications
|
39
|
+
- **No Patterns**: Prevents statistical analysis attacks
|
40
|
+
|
41
|
+
### Entropy Analysis
|
42
|
+
|
43
|
+
The security of opaque IDs depends on their entropy, which is calculated as:
|
44
|
+
|
45
|
+
```
|
46
|
+
Entropy = length × log₂(alphabet_size)
|
47
|
+
```
|
48
|
+
|
49
|
+
#### Entropy Examples
|
50
|
+
|
51
|
+
| ID Length | Alphabet | Entropy (bits) | Security Level |
|
52
|
+
| --------- | ----------------- | -------------- | -------------- |
|
53
|
+
| 21 | Alphanumeric (62) | 125.0 | Very High |
|
54
|
+
| 21 | Standard (64) | 126.0 | Very High |
|
55
|
+
| 15 | Hexadecimal (16) | 60.0 | High |
|
56
|
+
| 12 | Numeric (10) | 39.9 | Medium |
|
57
|
+
| 8 | Alphanumeric (62) | 47.7 | Medium |
|
58
|
+
|
59
|
+
#### Security Recommendations
|
60
|
+
|
61
|
+
```ruby
|
62
|
+
# High security applications (125+ bits entropy)
|
63
|
+
class ApiKey < ApplicationRecord
|
64
|
+
include OpaqueId::Model
|
65
|
+
|
66
|
+
self.opaque_id_length = 21
|
67
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
68
|
+
# Entropy: 125 bits
|
69
|
+
end
|
70
|
+
|
71
|
+
# Medium security applications (60+ bits entropy)
|
72
|
+
class User < ApplicationRecord
|
73
|
+
include OpaqueId::Model
|
74
|
+
|
75
|
+
self.opaque_id_length = 15
|
76
|
+
self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
|
77
|
+
# Entropy: 90 bits
|
78
|
+
end
|
79
|
+
|
80
|
+
# Low security applications (40+ bits entropy)
|
81
|
+
class ShortUrl < ApplicationRecord
|
82
|
+
include OpaqueId::Model
|
83
|
+
|
84
|
+
self.opaque_id_length = 8
|
85
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
86
|
+
# Entropy: 48 bits
|
87
|
+
end
|
88
|
+
```
|
89
|
+
|
90
|
+
## Security Best Practices
|
91
|
+
|
92
|
+
### DO: Recommended Practices
|
93
|
+
|
94
|
+
#### 1. Use Appropriate ID Length
|
95
|
+
|
96
|
+
```ruby
|
97
|
+
# High security: 21+ characters
|
98
|
+
self.opaque_id_length = 21
|
99
|
+
|
100
|
+
# Medium security: 15+ characters
|
101
|
+
self.opaque_id_length = 15
|
102
|
+
|
103
|
+
# Low security: 8+ characters
|
104
|
+
self.opaque_id_length = 8
|
105
|
+
```
|
106
|
+
|
107
|
+
#### 2. Choose Secure Alphabets
|
108
|
+
|
109
|
+
```ruby
|
110
|
+
# High entropy alphabets
|
111
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET # 62 characters
|
112
|
+
self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET # 64 characters
|
113
|
+
|
114
|
+
# Avoid low entropy alphabets for security-critical applications
|
115
|
+
# self.opaque_id_alphabet = "0123456789" # Only 10 characters
|
116
|
+
```
|
117
|
+
|
118
|
+
#### 3. Implement Proper Access Controls
|
119
|
+
|
120
|
+
```ruby
|
121
|
+
# Secure API endpoints
|
122
|
+
class UsersController < ApplicationController
|
123
|
+
before_action :authenticate_user!
|
124
|
+
before_action :authorize_user_access!
|
125
|
+
|
126
|
+
def show
|
127
|
+
@user = User.find_by_opaque_id!(params[:id])
|
128
|
+
# Additional authorization checks
|
129
|
+
end
|
130
|
+
end
|
131
|
+
```
|
132
|
+
|
133
|
+
#### 4. Use HTTPS in Production
|
134
|
+
|
135
|
+
```ruby
|
136
|
+
# Ensure opaque IDs are transmitted securely
|
137
|
+
# Use HTTPS for all API endpoints
|
138
|
+
# Implement proper CORS policies
|
139
|
+
# Use secure cookies for session management
|
140
|
+
```
|
141
|
+
|
142
|
+
#### 5. Implement Rate Limiting
|
143
|
+
|
144
|
+
```ruby
|
145
|
+
# Protect against brute force attacks
|
146
|
+
class ApiController < ApplicationController
|
147
|
+
before_action :rate_limit_requests
|
148
|
+
|
149
|
+
private
|
150
|
+
|
151
|
+
def rate_limit_requests
|
152
|
+
# Implement rate limiting
|
153
|
+
# Use Redis or similar for distributed rate limiting
|
154
|
+
# Log suspicious activity
|
155
|
+
end
|
156
|
+
end
|
157
|
+
```
|
158
|
+
|
159
|
+
### DON'T: Security Anti-Patterns
|
160
|
+
|
161
|
+
#### 1. Don't Use Predictable Patterns
|
162
|
+
|
163
|
+
```ruby
|
164
|
+
# BAD: Sequential or predictable IDs
|
165
|
+
self.opaque_id_alphabet = "0123456789"
|
166
|
+
self.opaque_id_length = 6
|
167
|
+
# Generates: 000001, 000002, 000003, etc.
|
168
|
+
|
169
|
+
# GOOD: Random, unpredictable IDs
|
170
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
171
|
+
self.opaque_id_length = 21
|
172
|
+
# Generates: V1StGXR8_Z5jdHi6B-myT, K8jH2mN9_pL3qR7sT1v, etc.
|
173
|
+
```
|
174
|
+
|
175
|
+
#### 2. Don't Expose Internal Information
|
176
|
+
|
177
|
+
```ruby
|
178
|
+
# BAD: Using database IDs in URLs
|
179
|
+
def user_path(user)
|
180
|
+
"/users/#{user.id}" # Exposes internal ID
|
181
|
+
end
|
182
|
+
|
183
|
+
# GOOD: Using opaque IDs in URLs
|
184
|
+
def user_path(user)
|
185
|
+
"/users/#{user.opaque_id}" # No internal information exposed
|
186
|
+
end
|
187
|
+
```
|
188
|
+
|
189
|
+
#### 3. Don't Use Weak Entropy
|
190
|
+
|
191
|
+
```ruby
|
192
|
+
# BAD: Low entropy for security-critical applications
|
193
|
+
class ApiKey < ApplicationRecord
|
194
|
+
include OpaqueId::Model
|
195
|
+
|
196
|
+
self.opaque_id_length = 8
|
197
|
+
self.opaque_id_alphabet = "0123456789"
|
198
|
+
# Only 26.6 bits of entropy
|
199
|
+
end
|
200
|
+
|
201
|
+
# GOOD: High entropy for security-critical applications
|
202
|
+
class ApiKey < ApplicationRecord
|
203
|
+
include OpaqueId::Model
|
204
|
+
|
205
|
+
self.opaque_id_length = 32
|
206
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
207
|
+
# 190.7 bits of entropy
|
208
|
+
end
|
209
|
+
```
|
210
|
+
|
211
|
+
#### 4. Don't Log Sensitive IDs
|
212
|
+
|
213
|
+
```ruby
|
214
|
+
# BAD: Logging opaque IDs
|
215
|
+
Rails.logger.info "User #{user.opaque_id} logged in"
|
216
|
+
|
217
|
+
# GOOD: Logging without sensitive information
|
218
|
+
Rails.logger.info "User #{user.id} logged in"
|
219
|
+
```
|
220
|
+
|
221
|
+
## Security Recommendations
|
222
|
+
|
223
|
+
### ID Length Recommendations
|
224
|
+
|
225
|
+
#### High Security (125+ bits entropy)
|
226
|
+
|
227
|
+
```ruby
|
228
|
+
# API keys, authentication tokens, sensitive data
|
229
|
+
self.opaque_id_length = 21
|
230
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
231
|
+
# Entropy: 125 bits
|
232
|
+
# Collision probability: 2.3×10⁻¹⁵ (1M IDs)
|
233
|
+
```
|
234
|
+
|
235
|
+
#### Medium Security (60+ bits entropy)
|
236
|
+
|
237
|
+
```ruby
|
238
|
+
# User IDs, order numbers, general identifiers
|
239
|
+
self.opaque_id_length = 15
|
240
|
+
self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
|
241
|
+
# Entropy: 90 bits
|
242
|
+
# Collision probability: 2.3×10⁻⁶ (1M IDs)
|
243
|
+
```
|
244
|
+
|
245
|
+
#### Low Security (40+ bits entropy)
|
246
|
+
|
247
|
+
```ruby
|
248
|
+
# Short URLs, public identifiers, non-sensitive data
|
249
|
+
self.opaque_id_length = 8
|
250
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
251
|
+
# Entropy: 48 bits
|
252
|
+
# Collision probability: 2.3×10⁻² (1M IDs)
|
253
|
+
```
|
254
|
+
|
255
|
+
### Alphabet Selection
|
256
|
+
|
257
|
+
#### High Security Alphabets
|
258
|
+
|
259
|
+
```ruby
|
260
|
+
# Maximum entropy
|
261
|
+
self.opaque_id_alphabet = OpaqueId::STANDARD_ALPHABET
|
262
|
+
# 64 characters: A-Z, a-z, 0-9, -, _
|
263
|
+
|
264
|
+
# High entropy, URL-safe
|
265
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
266
|
+
# 62 characters: A-Z, a-z, 0-9
|
267
|
+
```
|
268
|
+
|
269
|
+
#### Medium Security Alphabets
|
270
|
+
|
271
|
+
```ruby
|
272
|
+
# Hexadecimal
|
273
|
+
self.opaque_id_alphabet = "0123456789abcdef"
|
274
|
+
# 16 characters: 0-9, a-f
|
275
|
+
|
276
|
+
# Uppercase alphanumeric
|
277
|
+
self.opaque_id_alphabet = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"
|
278
|
+
# 36 characters: A-Z, 0-9
|
279
|
+
```
|
280
|
+
|
281
|
+
#### Low Security Alphabets
|
282
|
+
|
283
|
+
```ruby
|
284
|
+
# Numeric only
|
285
|
+
self.opaque_id_alphabet = "0123456789"
|
286
|
+
# 10 characters: 0-9
|
287
|
+
|
288
|
+
# Binary
|
289
|
+
self.opaque_id_alphabet = "01"
|
290
|
+
# 2 characters: 0, 1
|
291
|
+
```
|
292
|
+
|
293
|
+
## Threat Model Considerations
|
294
|
+
|
295
|
+
### Attack Vectors
|
296
|
+
|
297
|
+
#### 1. Brute Force Attacks
|
298
|
+
|
299
|
+
**Threat**: Attackers attempt to guess valid opaque IDs
|
300
|
+
|
301
|
+
**Mitigation**:
|
302
|
+
|
303
|
+
```ruby
|
304
|
+
# Use sufficient entropy
|
305
|
+
self.opaque_id_length = 21
|
306
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
307
|
+
|
308
|
+
# Implement rate limiting
|
309
|
+
# Monitor for suspicious activity
|
310
|
+
# Use proper authentication
|
311
|
+
```
|
312
|
+
|
313
|
+
**Analysis**:
|
314
|
+
|
315
|
+
- 21-character alphanumeric ID: 62²¹ ≈ 2.3×10³⁷ possible values
|
316
|
+
- Time to brute force: Extremely long (exponential with ID length and alphabet size)
|
317
|
+
|
318
|
+
#### 2. Timing Attacks
|
319
|
+
|
320
|
+
**Threat**: Attackers use timing information to predict IDs
|
321
|
+
|
322
|
+
**Mitigation**:
|
323
|
+
|
324
|
+
```ruby
|
325
|
+
# OpaqueId uses constant-time operations
|
326
|
+
# SecureRandom provides timing-attack resistance
|
327
|
+
# No predictable patterns in generation
|
328
|
+
```
|
329
|
+
|
330
|
+
**Analysis**:
|
331
|
+
|
332
|
+
- Bitwise operations have predictable timing
|
333
|
+
- Rejection sampling doesn't leak information
|
334
|
+
- SecureRandom prevents timing-based prediction
|
335
|
+
|
336
|
+
#### 3. Statistical Attacks
|
337
|
+
|
338
|
+
**Threat**: Attackers analyze patterns in generated IDs
|
339
|
+
|
340
|
+
**Mitigation**:
|
341
|
+
|
342
|
+
```ruby
|
343
|
+
# Uniform distribution through rejection sampling
|
344
|
+
# Cryptographically secure randomness
|
345
|
+
# No statistical patterns
|
346
|
+
```
|
347
|
+
|
348
|
+
**Analysis**:
|
349
|
+
|
350
|
+
- Rejection sampling ensures uniform distribution
|
351
|
+
- SecureRandom prevents pattern detection
|
352
|
+
- High entropy prevents statistical analysis
|
353
|
+
|
354
|
+
#### 4. Collision Attacks
|
355
|
+
|
356
|
+
**Threat**: Attackers attempt to generate duplicate IDs
|
357
|
+
|
358
|
+
**Mitigation**:
|
359
|
+
|
360
|
+
```ruby
|
361
|
+
# Built-in collision detection
|
362
|
+
self.opaque_id_max_retry = 5
|
363
|
+
|
364
|
+
# Database constraints
|
365
|
+
add_index :users, :opaque_id, unique: true
|
366
|
+
|
367
|
+
# Monitor for collision attempts
|
368
|
+
```
|
369
|
+
|
370
|
+
**Analysis**:
|
371
|
+
|
372
|
+
- Collision probability: 2.3×10⁻¹⁵ (1M IDs)
|
373
|
+
- Automatic retry on collision
|
374
|
+
- Database constraints prevent duplicates
|
375
|
+
|
376
|
+
### Security Audit Checklist
|
377
|
+
|
378
|
+
#### ✅ Cryptographic Security
|
379
|
+
|
380
|
+
- [ ] Uses `SecureRandom` for all random generation
|
381
|
+
- [ ] No predictable patterns in ID generation
|
382
|
+
- [ ] Sufficient entropy for security requirements
|
383
|
+
- [ ] No timing attack vulnerabilities
|
384
|
+
|
385
|
+
#### ✅ Access Control
|
386
|
+
|
387
|
+
- [ ] Proper authentication on all endpoints
|
388
|
+
- [ ] Authorization checks for ID access
|
389
|
+
- [ ] Rate limiting implemented
|
390
|
+
- [ ] Input validation on all parameters
|
391
|
+
|
392
|
+
#### ✅ Data Protection
|
393
|
+
|
394
|
+
- [ ] Opaque IDs not logged in plaintext
|
395
|
+
- [ ] HTTPS used for all transmissions
|
396
|
+
- [ ] Proper CORS policies implemented
|
397
|
+
- [ ] Sensitive data not exposed in URLs
|
398
|
+
|
399
|
+
#### ✅ Monitoring
|
400
|
+
|
401
|
+
- [ ] Logging of suspicious activity
|
402
|
+
- [ ] Monitoring for brute force attempts
|
403
|
+
- [ ] Alerting on security events
|
404
|
+
- [ ] Regular security audits
|
405
|
+
|
406
|
+
#### ✅ Configuration
|
407
|
+
|
408
|
+
- [ ] Appropriate ID length for security level
|
409
|
+
- [ ] Secure alphabet selection
|
410
|
+
- [ ] Proper collision handling
|
411
|
+
- [ ] Error handling for generation failures
|
412
|
+
|
413
|
+
## Implementation Security
|
414
|
+
|
415
|
+
### Secure Generation
|
416
|
+
|
417
|
+
```ruby
|
418
|
+
class SecureIdGenerator
|
419
|
+
def self.generate_secure_id(length: 21, alphabet: OpaqueId::ALPHANUMERIC_ALPHABET)
|
420
|
+
# Validate parameters
|
421
|
+
raise ArgumentError, "Length must be positive" unless length.positive?
|
422
|
+
raise ArgumentError, "Alphabet cannot be empty" if alphabet.nil? || alphabet.empty?
|
423
|
+
|
424
|
+
# Generate secure ID
|
425
|
+
OpaqueId.generate(size: length, alphabet: alphabet)
|
426
|
+
rescue => e
|
427
|
+
# Log security events
|
428
|
+
Rails.logger.error "Secure ID generation failed: #{e.message}"
|
429
|
+
raise
|
430
|
+
end
|
431
|
+
end
|
432
|
+
```
|
433
|
+
|
434
|
+
### Secure Storage
|
435
|
+
|
436
|
+
```ruby
|
437
|
+
# Database security
|
438
|
+
class AddOpaqueIdToUsers < ActiveRecord::Migration[8.0]
|
439
|
+
def change
|
440
|
+
add_column :users, :opaque_id, :string, null: false
|
441
|
+
add_index :users, :opaque_id, unique: true
|
442
|
+
|
443
|
+
# Additional security constraints
|
444
|
+
add_check_constraint :users, "length(opaque_id) >= 8", name: "opaque_id_length_check"
|
445
|
+
end
|
446
|
+
end
|
447
|
+
```
|
448
|
+
|
449
|
+
### Secure Access
|
450
|
+
|
451
|
+
```ruby
|
452
|
+
class UsersController < ApplicationController
|
453
|
+
before_action :authenticate_user!
|
454
|
+
before_action :authorize_user_access!
|
455
|
+
|
456
|
+
def show
|
457
|
+
@user = User.find_by_opaque_id!(params[:id])
|
458
|
+
|
459
|
+
# Additional security checks
|
460
|
+
unless current_user.can_access?(@user)
|
461
|
+
raise SecurityError, "Unauthorized access attempt"
|
462
|
+
end
|
463
|
+
end
|
464
|
+
|
465
|
+
private
|
466
|
+
|
467
|
+
def authorize_user_access!
|
468
|
+
# Implement proper authorization
|
469
|
+
# Check user permissions
|
470
|
+
# Validate access rights
|
471
|
+
end
|
472
|
+
end
|
473
|
+
```
|
474
|
+
|
475
|
+
## Security Monitoring
|
476
|
+
|
477
|
+
### Logging Security Events
|
478
|
+
|
479
|
+
```ruby
|
480
|
+
class SecurityLogger
|
481
|
+
def self.log_id_generation(user_id, opaque_id_length)
|
482
|
+
Rails.logger.info "Generated opaque ID for user #{user_id}, length: #{opaque_id_length}"
|
483
|
+
end
|
484
|
+
|
485
|
+
def self.log_suspicious_activity(ip_address, user_agent, opaque_id)
|
486
|
+
Rails.logger.warn "Suspicious activity detected: IP #{ip_address}, UA #{user_agent}, ID #{opaque_id}"
|
487
|
+
end
|
488
|
+
|
489
|
+
def self.log_collision_attempt(opaque_id, retry_count)
|
490
|
+
Rails.logger.error "Collision detected: ID #{opaque_id}, retry #{retry_count}"
|
491
|
+
end
|
492
|
+
end
|
493
|
+
```
|
494
|
+
|
495
|
+
### Monitoring and Alerting
|
496
|
+
|
497
|
+
```ruby
|
498
|
+
class SecurityMonitor
|
499
|
+
def self.monitor_brute_force_attempts
|
500
|
+
# Monitor for rapid ID generation attempts
|
501
|
+
# Alert on suspicious patterns
|
502
|
+
# Block malicious IPs
|
503
|
+
end
|
504
|
+
|
505
|
+
def self.monitor_collision_attempts
|
506
|
+
# Monitor for collision attempts
|
507
|
+
# Alert on high collision rates
|
508
|
+
# Investigate potential attacks
|
509
|
+
end
|
510
|
+
|
511
|
+
def self.monitor_access_patterns
|
512
|
+
# Monitor access patterns
|
513
|
+
# Detect unusual behavior
|
514
|
+
# Alert on security violations
|
515
|
+
end
|
516
|
+
end
|
517
|
+
```
|
518
|
+
|
519
|
+
## Compliance and Standards
|
520
|
+
|
521
|
+
### Security Standards
|
522
|
+
|
523
|
+
OpaqueId complies with various security standards:
|
524
|
+
|
525
|
+
- **FIPS 140-2**: Uses approved random number generators
|
526
|
+
- **Common Criteria**: Provides security functionality
|
527
|
+
- **ISO 27001**: Implements security controls
|
528
|
+
- **SOC 2**: Meets security requirements
|
529
|
+
|
530
|
+
### Compliance Requirements
|
531
|
+
|
532
|
+
```ruby
|
533
|
+
# HIPAA compliance for healthcare applications
|
534
|
+
class Patient < ApplicationRecord
|
535
|
+
include OpaqueId::Model
|
536
|
+
|
537
|
+
# High entropy for patient data
|
538
|
+
self.opaque_id_length = 32
|
539
|
+
self.opaque_id_alphabet = OpaqueId::ALPHANUMERIC_ALPHABET
|
540
|
+
|
541
|
+
# Audit logging
|
542
|
+
after_create :log_patient_id_generation
|
543
|
+
|
544
|
+
private
|
545
|
+
|
546
|
+
def log_patient_id_generation
|
547
|
+
AuditLog.create!(
|
548
|
+
action: 'patient_id_generated',
|
549
|
+
patient_id: id,
|
550
|
+
opaque_id: opaque_id,
|
551
|
+
timestamp: Time.current
|
552
|
+
)
|
553
|
+
end
|
554
|
+
end
|
555
|
+
```
|
556
|
+
|
557
|
+
## Best Practices Summary
|
558
|
+
|
559
|
+
### 1. Choose Appropriate Security Level
|
560
|
+
|
561
|
+
```ruby
|
562
|
+
# High security: 21+ characters, 125+ bits entropy
|
563
|
+
# Medium security: 15+ characters, 60+ bits entropy
|
564
|
+
# Low security: 8+ characters, 40+ bits entropy
|
565
|
+
```
|
566
|
+
|
567
|
+
### 2. Implement Defense in Depth
|
568
|
+
|
569
|
+
```ruby
|
570
|
+
# Multiple security layers
|
571
|
+
# Authentication + Authorization
|
572
|
+
# Rate limiting + Monitoring
|
573
|
+
# Encryption + Audit logging
|
574
|
+
```
|
575
|
+
|
576
|
+
### 3. Monitor and Alert
|
577
|
+
|
578
|
+
```ruby
|
579
|
+
# Log security events
|
580
|
+
# Monitor for attacks
|
581
|
+
# Alert on violations
|
582
|
+
# Regular security audits
|
583
|
+
```
|
584
|
+
|
585
|
+
### 4. Follow Security Standards
|
586
|
+
|
587
|
+
```ruby
|
588
|
+
# Use HTTPS
|
589
|
+
# Implement proper access controls
|
590
|
+
# Follow OWASP guidelines
|
591
|
+
# Regular security updates
|
592
|
+
```
|
593
|
+
|
594
|
+
## Next Steps
|
595
|
+
|
596
|
+
Now that you understand security considerations:
|
597
|
+
|
598
|
+
1. **Explore [Performance](performance.md)** for security-performance trade-offs
|
599
|
+
2. **Check out [Algorithms](algorithms.md)** for technical security details
|
600
|
+
3. **Review [Configuration](configuration.md)** for secure configuration options
|
601
|
+
4. **Read [API Reference](api-reference.md)** for complete security documentation
|