atp-sdk 1.0.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.
Files changed (65) hide show
  1. package/CHANGELOG.md +111 -0
  2. package/LICENSE +201 -0
  3. package/README.md +633 -0
  4. package/dist/__tests__/setup.d.ts.map +1 -0
  5. package/dist/__tests__/setup.js +55 -0
  6. package/dist/__tests__/setup.js.map +1 -0
  7. package/dist/client/atp.d.ts.map +1 -0
  8. package/dist/client/atp.js +90 -0
  9. package/dist/client/atp.js.map +1 -0
  10. package/dist/client/audit.d.ts.map +1 -0
  11. package/dist/client/audit.js +125 -0
  12. package/dist/client/audit.js.map +1 -0
  13. package/dist/client/base.d.ts.map +1 -0
  14. package/dist/client/base.js +190 -0
  15. package/dist/client/base.js.map +1 -0
  16. package/dist/client/credentials.d.ts.map +1 -0
  17. package/dist/client/credentials.js +112 -0
  18. package/dist/client/credentials.js.map +1 -0
  19. package/dist/client/gateway.d.ts.map +1 -0
  20. package/dist/client/gateway.js +214 -0
  21. package/dist/client/gateway.js.map +1 -0
  22. package/dist/client/identity.d.ts.map +1 -0
  23. package/dist/client/identity.js +94 -0
  24. package/dist/client/identity.js.map +1 -0
  25. package/dist/client/permissions.d.ts.map +1 -0
  26. package/dist/client/permissions.js +132 -0
  27. package/dist/client/permissions.js.map +1 -0
  28. package/dist/index.cjs +89 -0
  29. package/dist/index.d.ts.map +1 -0
  30. package/dist/index.js +72 -0
  31. package/dist/index.js.map +1 -0
  32. package/dist/simple-agent.d.ts.map +1 -0
  33. package/dist/simple-agent.js +261 -0
  34. package/dist/simple-agent.js.map +1 -0
  35. package/dist/tsconfig.tsbuildinfo +1 -0
  36. package/dist/types.d.ts.map +1 -0
  37. package/dist/types.js +48 -0
  38. package/dist/types.js.map +1 -0
  39. package/dist/utils/crypto.d.ts.map +1 -0
  40. package/dist/utils/crypto.js +100 -0
  41. package/dist/utils/crypto.js.map +1 -0
  42. package/dist/utils/did.d.ts.map +1 -0
  43. package/dist/utils/did.js +225 -0
  44. package/dist/utils/did.js.map +1 -0
  45. package/dist/utils/jwt.d.ts.map +1 -0
  46. package/dist/utils/jwt.js +235 -0
  47. package/dist/utils/jwt.js.map +1 -0
  48. package/docs/README.md +362 -0
  49. package/docs/api/README.md +1077 -0
  50. package/docs/guides/authentication.md +667 -0
  51. package/docs/guides/best-practices.md +1004 -0
  52. package/docs/guides/configuration.md +588 -0
  53. package/docs/guides/error-handling.md +1073 -0
  54. package/docs/guides/troubleshooting.md +850 -0
  55. package/examples/01-basic-setup.js +53 -0
  56. package/examples/02-identity-management.js +130 -0
  57. package/examples/03-verifiable-credentials.js +234 -0
  58. package/examples/04-permissions-and-access-control.js +326 -0
  59. package/examples/05-audit-logging.js +310 -0
  60. package/examples/06-real-time-monitoring.js +302 -0
  61. package/examples/07-advanced-use-cases.js +584 -0
  62. package/examples/README.md +211 -0
  63. package/examples/index.js +135 -0
  64. package/examples/simple-3-line.ts +51 -0
  65. package/package.json +108 -0
@@ -0,0 +1,667 @@
1
+ # Authentication Guide
2
+
3
+ This guide covers all authentication methods and patterns supported by the ATP™ SDK.
4
+
5
+ ## Table of Contents
6
+
7
+ 1. [Authentication Overview](#authentication-overview)
8
+ 2. [DID-based Authentication](#did-based-authentication)
9
+ 3. [JWT Token Authentication](#jwt-token-authentication)
10
+ 4. [Multi-Factor Authentication](#multi-factor-authentication)
11
+ 5. [Service-to-Service Authentication](#service-to-service-authentication)
12
+ 6. [Token Management](#token-management)
13
+ 7. [Security Best Practices](#security-best-practices)
14
+
15
+ ## Authentication Overview
16
+
17
+ The ATP™ SDK supports multiple authentication methods:
18
+
19
+ - **DID + Private Key**: Self-sovereign identity authentication
20
+ - **JWT Tokens**: Bearer token authentication
21
+ - **API Keys**: Simple API key authentication
22
+ - **Certificate-based**: X.509 client certificate authentication
23
+ - **Multi-Factor**: Additional security layers
24
+
25
+ ## DID-based Authentication
26
+
27
+ ### Basic DID Authentication
28
+
29
+ The primary authentication method uses Decentralized Identifiers (DIDs) with cryptographic key pairs:
30
+
31
+ ```javascript
32
+ import { ATPClient, DIDUtils } from '@atp/sdk';
33
+
34
+ // Generate a new DID and key pair
35
+ const { did, keyPair } = await DIDUtils.generateDID({
36
+ network: 'testnet',
37
+ method: 'atp'
38
+ });
39
+
40
+ // Configure client with DID authentication
41
+ const client = new ATPClient({
42
+ baseUrl: 'http://localhost',
43
+ auth: {
44
+ did: did,
45
+ privateKey: keyPair.privateKey
46
+ }
47
+ });
48
+ ```
49
+
50
+ ### Loading Existing DIDs
51
+
52
+ ```javascript
53
+ // Load from environment variables
54
+ const client = new ATPClient({
55
+ baseUrl: 'http://localhost',
56
+ auth: {
57
+ did: process.env.ATP_DID,
58
+ privateKey: process.env.ATP_PRIVATE_KEY
59
+ }
60
+ });
61
+
62
+ // Load from secure key storage
63
+ import { loadKeyFromVault } from './key-management';
64
+
65
+ const privateKey = await loadKeyFromVault(process.env.KEY_ID);
66
+ client.setAuthentication({
67
+ did: 'did:atp:mainnet:your-identifier',
68
+ privateKey: privateKey
69
+ });
70
+ ```
71
+
72
+ ### DID Document Registration
73
+
74
+ Before using a DID for authentication, it must be registered:
75
+
76
+ ```javascript
77
+ // Generate DID and register with ATP network
78
+ const { did, document, keyPair } = await DIDUtils.generateDID();
79
+
80
+ // Register identity
81
+ await client.identity.register({
82
+ did: did,
83
+ document: document,
84
+ metadata: {
85
+ name: 'Your Application',
86
+ type: 'service',
87
+ purpose: 'API access'
88
+ }
89
+ });
90
+
91
+ console.log(`DID registered: ${did}`);
92
+ ```
93
+
94
+ ### DID Key Rotation
95
+
96
+ Regularly rotate cryptographic keys for security:
97
+
98
+ ```javascript
99
+ // Generate new key pair
100
+ const newKeyPair = await CryptoUtils.generateKeyPair();
101
+
102
+ // Add new verification method to DID document
103
+ const updatedDocument = DIDUtils.addVerificationMethod(
104
+ currentDocument,
105
+ newKeyPair.publicKey,
106
+ ['authentication', 'assertionMethod']
107
+ );
108
+
109
+ // Update DID document
110
+ await client.identity.update(did, {
111
+ document: updatedDocument
112
+ });
113
+
114
+ // Update client authentication
115
+ client.setAuthentication({
116
+ did: did,
117
+ privateKey: newKeyPair.privateKey
118
+ });
119
+
120
+ console.log('DID key rotated successfully');
121
+ ```
122
+
123
+ ## JWT Token Authentication
124
+
125
+ ### Using Pre-issued Tokens
126
+
127
+ If you have a JWT token from another system:
128
+
129
+ ```javascript
130
+ const client = new ATPClient({
131
+ baseUrl: 'http://localhost',
132
+ auth: {
133
+ token: 'eyJhbGciOiJFZERTQSIsInR5cCI6IkpXVCJ9...'
134
+ }
135
+ });
136
+ ```
137
+
138
+ ### Creating JWT Tokens
139
+
140
+ Create JWT tokens programmatically:
141
+
142
+ ```javascript
143
+ import { JWTUtils } from '@atp/sdk';
144
+
145
+ // Create authentication token
146
+ const token = await JWTUtils.createAuthToken(
147
+ 'did:atp:testnet:user',
148
+ privateKey,
149
+ {
150
+ audience: 'atp:services',
151
+ expiresIn: '1h',
152
+ permissions: ['read', 'write'],
153
+ trustLevel: 'VERIFIED'
154
+ }
155
+ );
156
+
157
+ // Use token with client
158
+ client.setAuthentication({ token });
159
+ ```
160
+
161
+ ### Token Verification
162
+
163
+ Verify incoming tokens:
164
+
165
+ ```javascript
166
+ // Verify token authenticity
167
+ const verification = await JWTUtils.verifyDIDJWT(
168
+ token,
169
+ publicKey,
170
+ {
171
+ audience: 'atp:services',
172
+ issuer: 'did:atp:testnet:trusted-issuer'
173
+ }
174
+ );
175
+
176
+ if (verification.valid) {
177
+ console.log('Token is valid');
178
+ console.log('Payload:', verification.payload);
179
+ } else {
180
+ console.error('Token verification failed:', verification.error);
181
+ }
182
+ ```
183
+
184
+ ### Capability Tokens
185
+
186
+ Use capability tokens for delegation:
187
+
188
+ ```javascript
189
+ // Create capability token
190
+ const capabilityToken = await JWTUtils.createCapabilityToken(
191
+ 'did:atp:testnet:issuer', // Issuer
192
+ 'did:atp:testnet:delegate', // Subject/delegate
193
+ ['document:read', 'report:generate'], // Capabilities
194
+ issuerPrivateKey,
195
+ {
196
+ expiresIn: '24h',
197
+ audience: 'atp:services',
198
+ restrictions: {
199
+ ipRange: '192.168.1.0/24',
200
+ timeWindow: {
201
+ start: '09:00',
202
+ end: '17:00'
203
+ }
204
+ }
205
+ }
206
+ );
207
+
208
+ // Use capability token
209
+ client.setAuthentication({ token: capabilityToken });
210
+ ```
211
+
212
+ ## Multi-Factor Authentication
213
+
214
+ ### Setting Up MFA
215
+
216
+ Enable MFA for enhanced security:
217
+
218
+ ```javascript
219
+ // Set up TOTP (Time-based One-Time Password)
220
+ const mfaSetup = await client.identity.setupMFA({
221
+ method: 'totp',
222
+ label: 'MyApp Production'
223
+ });
224
+
225
+ console.log('MFA Secret:', mfaSetup.data.secret);
226
+ console.log('QR Code:', mfaSetup.data.qrCodeUrl);
227
+
228
+ // Set up SMS MFA
229
+ const smsMfa = await client.identity.setupMFA({
230
+ method: 'sms',
231
+ phoneNumber: '+1234567890'
232
+ });
233
+
234
+ // Set up Email MFA
235
+ const emailMfa = await client.identity.setupMFA({
236
+ method: 'email',
237
+ emailAddress: 'user@example.com'
238
+ });
239
+ ```
240
+
241
+ ### MFA Authentication Flow
242
+
243
+ ```javascript
244
+ // Step 1: Initial authentication with DID
245
+ client.setAuthentication({
246
+ did: 'did:atp:testnet:user',
247
+ privateKey: userPrivateKey
248
+ });
249
+
250
+ // Step 2: Check if MFA is required
251
+ try {
252
+ await client.identity.resolve('did:atp:testnet:user');
253
+ } catch (error) {
254
+ if (error instanceof ATPAuthenticationError && error.code === 'MFA_REQUIRED') {
255
+ // MFA verification needed
256
+ const mfaCode = await promptUserForMFACode();
257
+
258
+ // Verify MFA
259
+ const mfaResult = await client.identity.verifyMFA({
260
+ method: 'totp',
261
+ code: mfaCode
262
+ });
263
+
264
+ if (mfaResult.data.verified) {
265
+ console.log('MFA verification successful');
266
+ // Client is now fully authenticated
267
+ }
268
+ }
269
+ }
270
+ ```
271
+
272
+ ### MFA Recovery
273
+
274
+ Handle MFA recovery scenarios:
275
+
276
+ ```javascript
277
+ // Generate recovery codes during MFA setup
278
+ const recoverySetup = await client.identity.setupMFARecovery({
279
+ codeCount: 10 // Generate 10 recovery codes
280
+ });
281
+
282
+ console.log('Recovery codes:', recoverySetup.data.recoveryCodes);
283
+
284
+ // Use recovery code when primary MFA is unavailable
285
+ const recoveryResult = await client.identity.verifyMFARecovery({
286
+ recoveryCode: 'RECOVERY-CODE-123'
287
+ });
288
+
289
+ if (recoveryResult.data.verified) {
290
+ // Disable compromised recovery code
291
+ await client.identity.revokeRecoveryCode('RECOVERY-CODE-123');
292
+ }
293
+ ```
294
+
295
+ ## Service-to-Service Authentication
296
+
297
+ ### Machine-to-Machine Authentication
298
+
299
+ For automated services:
300
+
301
+ ```javascript
302
+ // Service identity with long-lived credentials
303
+ const serviceConfig = {
304
+ baseUrl: 'https://api.atp.example.com',
305
+ auth: {
306
+ did: 'did:atp:mainnet:service-abc123',
307
+ privateKey: await loadServiceKey(),
308
+
309
+ // Service-specific options
310
+ serviceType: 'automated',
311
+ scope: ['audit:write', 'events:publish']
312
+ }
313
+ };
314
+
315
+ const serviceClient = new ATPClient(serviceConfig);
316
+ ```
317
+
318
+ ### Cross-Service Communication
319
+
320
+ Authenticate between ATP services:
321
+
322
+ ```javascript
323
+ // Create service-to-service token
324
+ const serviceToken = await JWTUtils.createDIDJWT(
325
+ {
326
+ service: 'audit-service',
327
+ operation: 'log_event',
328
+ requestId: generateRequestId()
329
+ },
330
+ servicePrivateKey,
331
+ 'did:atp:mainnet:audit-service',
332
+ {
333
+ audience: 'did:atp:mainnet:identity-service',
334
+ expiresIn: '5m' // Short-lived for service calls
335
+ }
336
+ );
337
+
338
+ // Use for inter-service communication
339
+ const response = await fetch('https://identity-service/api/validate', {
340
+ headers: {
341
+ 'Authorization': `Bearer ${serviceToken}`,
342
+ 'Content-Type': 'application/json'
343
+ },
344
+ body: JSON.stringify(requestData)
345
+ });
346
+ ```
347
+
348
+ ### Service Mesh Authentication
349
+
350
+ For microservices architectures:
351
+
352
+ ```javascript
353
+ // Load service mesh certificates
354
+ const serviceConfig = {
355
+ baseUrl: 'https://atp-mesh.internal',
356
+ tls: {
357
+ cert: fs.readFileSync('/etc/certs/service.crt'),
358
+ key: fs.readFileSync('/etc/certs/service.key'),
359
+ ca: fs.readFileSync('/etc/certs/ca.crt')
360
+ },
361
+ auth: {
362
+ method: 'mutual-tls',
363
+ serviceId: process.env.SERVICE_ID
364
+ }
365
+ };
366
+ ```
367
+
368
+ ## Token Management
369
+
370
+ ### Token Lifecycle
371
+
372
+ Manage token lifecycle automatically:
373
+
374
+ ```javascript
375
+ class TokenManager {
376
+ constructor(client, did, privateKey) {
377
+ this.client = client;
378
+ this.did = did;
379
+ this.privateKey = privateKey;
380
+ this.currentToken = null;
381
+ this.refreshToken = null;
382
+ }
383
+
384
+ async ensureValidToken() {
385
+ // Check if current token is expired
386
+ if (!this.currentToken || JWTUtils.isExpired(this.currentToken)) {
387
+ await this.refreshAuthToken();
388
+ }
389
+ return this.currentToken;
390
+ }
391
+
392
+ async refreshAuthToken() {
393
+ if (this.refreshToken && !JWTUtils.isExpired(this.refreshToken)) {
394
+ // Use refresh token
395
+ this.currentToken = await this.exchangeRefreshToken();
396
+ } else {
397
+ // Create new token with DID
398
+ this.currentToken = await JWTUtils.createAuthToken(
399
+ this.did,
400
+ this.privateKey,
401
+ { expiresIn: '1h' }
402
+ );
403
+
404
+ this.refreshToken = await JWTUtils.createRefreshToken(
405
+ this.did,
406
+ this.privateKey,
407
+ generateTokenId(),
408
+ { expiresIn: '30d' }
409
+ );
410
+ }
411
+
412
+ // Update client authentication
413
+ this.client.setAuthentication({ token: this.currentToken });
414
+ }
415
+
416
+ async exchangeRefreshToken() {
417
+ const response = await fetch('/auth/refresh', {
418
+ method: 'POST',
419
+ headers: {
420
+ 'Authorization': `Bearer ${this.refreshToken}`,
421
+ 'Content-Type': 'application/json'
422
+ }
423
+ });
424
+
425
+ const data = await response.json();
426
+ return data.accessToken;
427
+ }
428
+ }
429
+
430
+ // Usage
431
+ const tokenManager = new TokenManager(client, did, privateKey);
432
+ await tokenManager.ensureValidToken();
433
+ ```
434
+
435
+ ### Token Caching
436
+
437
+ Cache tokens to improve performance:
438
+
439
+ ```javascript
440
+ class CachedAuthClient {
441
+ constructor(config) {
442
+ this.client = new ATPClient(config);
443
+ this.tokenCache = new Map();
444
+ this.did = config.auth.did;
445
+ this.privateKey = config.auth.privateKey;
446
+ }
447
+
448
+ async authenticatedRequest(operation, ...args) {
449
+ const cacheKey = `token:${this.did}`;
450
+ let token = this.tokenCache.get(cacheKey);
451
+
452
+ // Check if token is expired or near expiry
453
+ if (!token || this.isTokenNearExpiry(token)) {
454
+ token = await this.generateFreshToken();
455
+ this.tokenCache.set(cacheKey, token);
456
+ this.client.setAuthentication({ token });
457
+ }
458
+
459
+ return await operation.apply(this.client, args);
460
+ }
461
+
462
+ isTokenNearExpiry(token) {
463
+ const timeToExpiry = JWTUtils.getTimeToExpiration(token);
464
+ return timeToExpiry < 300; // Refresh if less than 5 minutes remaining
465
+ }
466
+
467
+ async generateFreshToken() {
468
+ return await JWTUtils.createAuthToken(
469
+ this.did,
470
+ this.privateKey,
471
+ { expiresIn: '1h' }
472
+ );
473
+ }
474
+ }
475
+ ```
476
+
477
+ ### Token Revocation
478
+
479
+ Revoke compromised tokens:
480
+
481
+ ```javascript
482
+ // Revoke specific token
483
+ await client.identity.revokeToken({
484
+ tokenId: 'token-abc123',
485
+ reason: 'Security incident'
486
+ });
487
+
488
+ // Revoke all tokens for a DID
489
+ await client.identity.revokeAllTokens({
490
+ did: 'did:atp:testnet:user',
491
+ reason: 'Account compromise'
492
+ });
493
+
494
+ // Check token revocation status
495
+ const tokenStatus = await client.identity.checkTokenStatus('token-abc123');
496
+ if (tokenStatus.data.revoked) {
497
+ console.log('Token has been revoked');
498
+ }
499
+ ```
500
+
501
+ ## Security Best Practices
502
+
503
+ ### Key Management
504
+
505
+ 1. **Secure Storage**: Store private keys in secure vaults (HSMs, AWS KMS, etc.)
506
+ 2. **Key Rotation**: Rotate keys regularly
507
+ 3. **Separation**: Use different keys for different environments
508
+ 4. **Backup**: Securely backup recovery keys
509
+
510
+ ```javascript
511
+ // Example: AWS KMS integration
512
+ import { KMSClient, DecryptCommand } from '@aws-sdk/client-kms';
513
+
514
+ async function loadPrivateKeyFromKMS(keyId) {
515
+ const kmsClient = new KMSClient({ region: 'us-east-1' });
516
+
517
+ const command = new DecryptCommand({
518
+ CiphertextBlob: Buffer.from(process.env.ENCRYPTED_PRIVATE_KEY, 'base64')
519
+ });
520
+
521
+ const response = await kmsClient.send(command);
522
+ return Buffer.from(response.Plaintext).toString('hex');
523
+ }
524
+
525
+ // Use with client
526
+ const privateKey = await loadPrivateKeyFromKMS(process.env.KMS_KEY_ID);
527
+ client.setAuthentication({
528
+ did: process.env.ATP_DID,
529
+ privateKey: privateKey
530
+ });
531
+ ```
532
+
533
+ ### Token Security
534
+
535
+ 1. **Short Expiry**: Use short token lifetimes
536
+ 2. **Refresh Tokens**: Implement token refresh
537
+ 3. **Secure Transmission**: Always use HTTPS
538
+ 4. **Token Validation**: Validate tokens on every request
539
+
540
+ ```javascript
541
+ // Secure token configuration
542
+ const tokenConfig = {
543
+ accessTokenExpiry: '15m', // Short-lived access tokens
544
+ refreshTokenExpiry: '7d', // Longer-lived refresh tokens
545
+ audience: 'specific-service', // Limit token scope
546
+ issuer: 'trusted-issuer',
547
+
548
+ // Security headers
549
+ headers: {
550
+ 'Strict-Transport-Security': 'max-age=31536000',
551
+ 'X-Content-Type-Options': 'nosniff',
552
+ 'X-Frame-Options': 'DENY'
553
+ }
554
+ };
555
+ ```
556
+
557
+ ### Environment Separation
558
+
559
+ Separate credentials by environment:
560
+
561
+ ```javascript
562
+ // Environment-specific authentication
563
+ const authConfig = {
564
+ development: {
565
+ did: 'did:atp:testnet:dev-service',
566
+ privateKey: process.env.DEV_PRIVATE_KEY,
567
+ trustedIssuers: ['did:atp:testnet:dev-issuer']
568
+ },
569
+
570
+ staging: {
571
+ did: 'did:atp:testnet:staging-service',
572
+ privateKey: process.env.STAGING_PRIVATE_KEY,
573
+ trustedIssuers: ['did:atp:testnet:staging-issuer']
574
+ },
575
+
576
+ production: {
577
+ did: 'did:atp:mainnet:prod-service',
578
+ privateKey: await loadFromSecureVault(),
579
+ trustedIssuers: ['did:atp:mainnet:prod-issuer'],
580
+ mfaRequired: true
581
+ }
582
+ };
583
+
584
+ const config = authConfig[process.env.NODE_ENV || 'development'];
585
+ ```
586
+
587
+ ### Monitoring and Auditing
588
+
589
+ Monitor authentication events:
590
+
591
+ ```javascript
592
+ // Authentication event logging
593
+ client.on('auth:success', (event) => {
594
+ console.log(`Authentication successful: ${event.did}`);
595
+
596
+ // Log to audit service
597
+ client.audit.logEvent({
598
+ source: 'sdk-client',
599
+ action: 'authentication_success',
600
+ resource: 'auth:login',
601
+ actor: event.did,
602
+ details: {
603
+ method: event.method,
604
+ timestamp: new Date().toISOString(),
605
+ userAgent: process.env.USER_AGENT
606
+ }
607
+ });
608
+ });
609
+
610
+ client.on('auth:failure', (event) => {
611
+ console.error(`Authentication failed: ${event.error}`);
612
+
613
+ // Log security event
614
+ client.audit.logEvent({
615
+ source: 'sdk-client',
616
+ action: 'authentication_failure',
617
+ resource: 'auth:login',
618
+ details: {
619
+ error: event.error,
620
+ did: event.did,
621
+ timestamp: new Date().toISOString(),
622
+ severity: 'high'
623
+ }
624
+ });
625
+ });
626
+ ```
627
+
628
+ ### Error Handling
629
+
630
+ Handle authentication errors gracefully:
631
+
632
+ ```javascript
633
+ async function safeAuthentication(client, credentials) {
634
+ try {
635
+ client.setAuthentication(credentials);
636
+
637
+ // Test authentication
638
+ await client.identity.resolve(credentials.did);
639
+
640
+ return { success: true };
641
+
642
+ } catch (error) {
643
+ if (error instanceof ATPAuthenticationError) {
644
+ switch (error.code) {
645
+ case 'INVALID_DID':
646
+ return { success: false, error: 'Invalid DID format' };
647
+
648
+ case 'INVALID_SIGNATURE':
649
+ return { success: false, error: 'Invalid private key' };
650
+
651
+ case 'MFA_REQUIRED':
652
+ return { success: false, error: 'MFA verification required', requiresMFA: true };
653
+
654
+ case 'TOKEN_EXPIRED':
655
+ return { success: false, error: 'Token has expired', requiresRefresh: true };
656
+
657
+ default:
658
+ return { success: false, error: 'Authentication failed' };
659
+ }
660
+ }
661
+
662
+ throw error; // Re-throw non-auth errors
663
+ }
664
+ }
665
+ ```
666
+
667
+ This authentication guide covers all aspects of securing your ATP™ SDK integration. Always follow security best practices and regularly review your authentication implementation.