ldap-rest 0.1.3 → 0.1.5

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 (78) hide show
  1. package/README.md +31 -21
  2. package/dist/abstract/ldapFlat.js +1 -1
  3. package/dist/lib/ldapActions.js +1 -1
  4. package/dist/plugins/ldap/groups.js +1 -1
  5. package/dist/src/abstract/ldapFlat.d.ts +9 -0
  6. package/dist/src/browser/ldap-user-editor/components/UserTree.d.ts +2 -1
  7. package/dist/src/browser/shared/components/DisposableComponent.d.ts +29 -0
  8. package/dist/src/browser/shared/components/Modal.d.ts +6 -1
  9. package/dist/src/lib/ldapActions.d.ts +9 -0
  10. package/dist/src/plugins/ldap/groups.d.ts +9 -0
  11. package/docs/README.md +23 -486
  12. package/docs/{DEVELOPER_GUIDE.md → client-development/README.md} +24 -24
  13. package/docs/client-development/api/README.md +75 -0
  14. package/docs/client-development/browser/README.md +65 -0
  15. package/docs/{plugins/DEVELOPMENT.md → plugin-development/README.md} +4 -9
  16. package/docs/plugin-development/hooks.md +18 -0
  17. package/docs/usage/README.md +89 -0
  18. package/docs/usage/configuration.md +375 -0
  19. package/docs/usage/plugins/README.md +87 -0
  20. package/docs/usage/plugins/auth/README.md +65 -0
  21. package/docs/usage/plugins/auth/crowdsec.md +95 -0
  22. package/docs/usage/plugins/auth/hmac.md +293 -0
  23. package/docs/usage/plugins/auth/llng.md +99 -0
  24. package/docs/usage/plugins/auth/oidc.md +167 -0
  25. package/docs/usage/plugins/auth/rate-limit.md +62 -0
  26. package/docs/usage/plugins/auth/token.md +136 -0
  27. package/docs/usage/plugins/auth/totp.md +213 -0
  28. package/docs/usage/plugins/auth/trusted-proxy.md +127 -0
  29. package/docs/usage/plugins/integrations/README.md +42 -0
  30. package/docs/usage/plugins/ldap/README.md +79 -0
  31. package/docs/usage/troubleshooting.md +105 -0
  32. package/package.json +9 -1
  33. package/static/browser/ldap-user-editor/components/UserTree.js +6 -3
  34. package/static/browser/ldap-user-editor/components/UserTree.js.map +1 -1
  35. package/static/browser/ldap-user-editor.esm.js +62 -3
  36. package/static/browser/ldap-user-editor.esm.js.map +1 -1
  37. package/static/browser/ldap-user-editor.js +62 -3
  38. package/static/browser/ldap-user-editor.js.map +1 -1
  39. package/static/browser/ldap-user-editor.min.js +1 -1
  40. package/static/browser/ldap-user-editor.min.js.map +1 -1
  41. package/static/browser/shared/components/DisposableComponent.js +59 -0
  42. package/static/browser/shared/components/DisposableComponent.js.map +1 -0
  43. package/static/browser/shared/components/Modal.js +16 -6
  44. package/static/browser/shared/components/Modal.js.map +1 -1
  45. package/static/browser/shared.esm.js +72 -6
  46. package/static/browser/shared.esm.js.map +1 -1
  47. package/static/browser/shared.js +72 -6
  48. package/static/browser/shared.js.map +1 -1
  49. package/static/browser/shared.min.js +1 -1
  50. package/static/browser/shared.min.js.map +1 -1
  51. package/docs/authentication.md +0 -1194
  52. /package/docs/{OPENAPI.md → client-development/api/openapi.md} +0 -0
  53. /package/docs/{api/REFERENCE.md → client-development/api/reference.md} +0 -0
  54. /package/docs/{api/REST_API.md → client-development/api/rest-api.md} +0 -0
  55. /package/docs/{browser/LIBRARIES.md → client-development/browser/libraries.md} +0 -0
  56. /package/docs/{examples/EXAMPLES.md → client-development/examples/README.md} +0 -0
  57. /package/docs/{examples → client-development/examples/ldif}/twake-mailbox-type-nomenclature.ldif +0 -0
  58. /package/docs/{examples → client-development/examples/ldif}/twake-mailbox-type-schema-amendment.ldif +0 -0
  59. /package/docs/{schemas/SCHEMAS.md → client-development/schemas/README.md} +0 -0
  60. /package/docs/{PLUGIN_DEPENDENCIES.md → plugin-development/dependencies.md} +0 -0
  61. /package/docs/{testing-with-embedded-ldap.md → plugin-development/testing.md} +0 -0
  62. /package/docs/{presenterm.md → presentations/en.md} +0 -0
  63. /package/docs/{presenterm-fr.md → presentations/fr.md} +0 -0
  64. /package/docs/{authzLinid1.md → usage/plugins/auth/authz-linid1.md} +0 -0
  65. /package/docs/{authzPerBranch.md → usage/plugins/auth/authz-per-branch.md} +0 -0
  66. /package/docs/{twakeAppAccountsApi.md → usage/plugins/integrations/app-accounts.md} +0 -0
  67. /package/docs/{twakeCalendarResources.md → usage/plugins/integrations/calendar-resources.md} +0 -0
  68. /package/docs/{twakeJames.md → usage/plugins/integrations/james-mail.md} +0 -0
  69. /package/docs/{jamesTeamMailboxes.md → usage/plugins/integrations/james-mailboxes.md} +0 -0
  70. /package/docs/{ldapBulkImport.md → usage/plugins/ldap/bulk-import.md} +0 -0
  71. /package/docs/{ldapExternalUsersInGroups.md → usage/plugins/ldap/external-users.md} +0 -0
  72. /package/docs/{ldapFlatGeneric.md → usage/plugins/ldap/flat-generic.md} +0 -0
  73. /package/docs/{ldapGroups.md → usage/plugins/ldap/groups.md} +0 -0
  74. /package/docs/{onChange.md → usage/plugins/ldap/on-change.md} +0 -0
  75. /package/docs/{ldapOrganizations.md → usage/plugins/ldap/organizations.md} +0 -0
  76. /package/docs/{ldapTrash.md → usage/plugins/ldap/trash.md} +0 -0
  77. /package/docs/{static.md → usage/plugins/utilities/static.md} +0 -0
  78. /package/docs/{weblogs.md → usage/plugins/utilities/weblogs.md} +0 -0
@@ -0,0 +1,87 @@
1
+ # Plugins
2
+
3
+ LDAP-Rest is extensible through a plugin system. This section documents all available plugins.
4
+
5
+ ## LDAP Plugins
6
+
7
+ LDAP entity management:
8
+
9
+ | Plugin | Description |
10
+ | ---------------------------------------- | ------------------------------------------------------- |
11
+ | [flat-generic](ldap/flat-generic.md) | Generic LDAP entity management (users, positions, etc.) |
12
+ | [groups](ldap/groups.md) | LDAP group management with member validation |
13
+ | [organizations](ldap/organizations.md) | Hierarchical organization management |
14
+ | [bulk-import](ldap/bulk-import.md) | Bulk import from CSV |
15
+ | [trash](ldap/trash.md) | Trash system (soft delete) |
16
+ | [external-users](ldap/external-users.md) | Automatic external contact creation |
17
+ | [on-change](ldap/on-change.md) | LDAP change detection |
18
+
19
+ ## Authentication Plugins
20
+
21
+ Secure API access:
22
+
23
+ | Plugin | Description |
24
+ | ---------------------- | ---------------------------------------- |
25
+ | [token](auth/token.md) | Bearer token authentication |
26
+ | [totp](auth/totp.md) | TOTP authentication (time-based codes) |
27
+ | [hmac](auth/hmac.md) | HMAC-SHA256 signing for backend services |
28
+ | [llng](auth/llng.md) | LemonLDAP::NG SSO integration |
29
+ | [oidc](auth/oidc.md) | OpenID Connect / OAuth 2.0 |
30
+
31
+ ## Authorization Plugins
32
+
33
+ Access control:
34
+
35
+ | Plugin | Description |
36
+ | -------------------------------------------- | ------------------------------- |
37
+ | [authz-per-branch](auth/authz-per-branch.md) | Branch-level LDAP authorization |
38
+ | [authz-linid1](auth/authz-linid1.md) | LinID 1.x integration |
39
+
40
+ ## Security Plugins
41
+
42
+ Protection and rate limiting:
43
+
44
+ | Plugin | Description |
45
+ | -------------------------------------- | --------------------------------- |
46
+ | [trusted-proxy](auth/trusted-proxy.md) | X-Forwarded-For header validation |
47
+ | [rate-limit](auth/rate-limit.md) | Request rate limiting |
48
+ | [crowdsec](auth/crowdsec.md) | IP blocking via CrowdSec |
49
+
50
+ ## Integration Plugins
51
+
52
+ Connect to external systems:
53
+
54
+ | Plugin | Description |
55
+ | -------------------------------------------------------- | ---------------------------- |
56
+ | [james-mail](integrations/james-mail.md) | Apache James synchronization |
57
+ | [james-mailboxes](integrations/james-mailboxes.md) | Apache James team mailboxes |
58
+ | [calendar-resources](integrations/calendar-resources.md) | Twake calendar resources |
59
+ | [app-accounts](integrations/app-accounts.md) | Applicative accounts API |
60
+
61
+ ## Utility Plugins
62
+
63
+ | Plugin | Description |
64
+ | ------------------------------- | ------------------ |
65
+ | [static](utilities/static.md) | Static file server |
66
+ | [weblogs](utilities/weblogs.md) | HTTP logging |
67
+
68
+ ## Plugin Dependencies
69
+
70
+ Some plugins require other plugins:
71
+
72
+ ```
73
+ core/twake/james
74
+ └─ requires: core/ldap/onChange
75
+
76
+ core/ldap/externalUsersInGroups
77
+ └─ requires: core/ldap/groups
78
+
79
+ core/auth/authzPerBranch
80
+ └─ requires: An authentication plugin
81
+ ```
82
+
83
+ See [the complete dependencies matrix](../../plugin-development/dependencies.md).
84
+
85
+ ## Load Order
86
+
87
+ Authentication plugins are loaded first to secure API endpoints. The order is defined in `src/plugins/priority.json`.
@@ -0,0 +1,65 @@
1
+ # Authentication Plugins
2
+
3
+ LDAP-Rest provides multiple authentication plugins to secure API access. These plugins can be used individually or combined depending on your infrastructure requirements.
4
+
5
+ ## Available Authentication Methods
6
+
7
+ | Method | Plugin | Description |
8
+ | ------------------------- | ------------------------- | ------------------------------------------------ |
9
+ | [Token](token.md) | `core/auth/token` | Simple bearer token authentication |
10
+ | [TOTP](totp.md) | `core/auth/totp` | Time-based One-Time Password authentication |
11
+ | [HMAC](hmac.md) | `core/auth/hmac` | HMAC-SHA256 request signing for backend services |
12
+ | [LemonLDAP::NG](llng.md) | `core/auth/llng` | Integration with LemonLDAP::NG SSO |
13
+ | [OpenID Connect](oidc.md) | `core/auth/openidconnect` | OAuth 2.0 / OpenID Connect authentication |
14
+
15
+ ## Authorization Plugins
16
+
17
+ | Method | Plugin | Description |
18
+ | ----------------------------------------------- | -------------------------- | --------------------------- |
19
+ | [Authorization Per Branch](authz-per-branch.md) | `core/auth/authzPerBranch` | Branch-level access control |
20
+ | [Authorization LinID 1.x](authz-linid1.md) | `core/auth/authzLinid1` | LinID 1.x integration |
21
+
22
+ ## Security Plugins
23
+
24
+ | Method | Plugin | Description |
25
+ | --------------------------------- | ------------------------ | ----------------------------------------------------- |
26
+ | [Trusted Proxy](trusted-proxy.md) | `core/auth/trustedProxy` | Validate X-Forwarded-For headers from reverse proxies |
27
+ | [Rate Limiting](rate-limit.md) | `core/auth/rateLimit` | Prevent brute force attacks |
28
+ | [CrowdSec](crowdsec.md) | `core/auth/crowdsec` | IP reputation and blocking |
29
+
30
+ ## Choosing an Authentication Method
31
+
32
+ | Feature | Token | TOTP | HMAC | LemonLDAP::NG | OpenID Connect |
33
+ | ---------------------- | ------------- | ----------------- | ---------------------- | --------------------- | -------------------------------- |
34
+ | **Setup Complexity** | Simple | Simple | Medium | Medium | Medium |
35
+ | **User Management** | None | Manual | Manual (service-based) | External (LLNG) | External (Provider) |
36
+ | **SSO Support** | No | No | No | Yes | Yes |
37
+ | **MFA Support** | No | Yes (TOTP itself) | N/A | Yes (via LLNG) | Yes (via Provider) |
38
+ | **Session Management** | Stateless | Stateless | Stateless | LLNG Sessions | OIDC Sessions |
39
+ | **Code Expiration** | Never | 30-60 seconds | Per-request | Session-based | Session-based |
40
+ | **Request Integrity** | No | No | Yes (body + path hash) | No | No |
41
+ | **Replay Protection** | No | Yes (time-based) | Yes (timestamp) | Session-based | Session-based |
42
+ | **Best For** | APIs, Scripts | APIs, Enhanced | Backend Services | Enterprises with LLNG | Cloud/SaaS, Enterprises with SSO |
43
+ | **Dependencies** | None | None | None | lemonldap-ng-handler | express-openid-connect |
44
+
45
+ ## Combining with Authorization
46
+
47
+ All authentication plugins set `req.user` to the authenticated identity. You can use hooks to implement custom authorization:
48
+
49
+ ```javascript
50
+ hooks: {
51
+ afterAuth: async ([req, res]) => {
52
+ // Check if user can access this endpoint
53
+ if (req.path.startsWith('/api/v1/ldap/users') && !isAdmin(req.user)) {
54
+ throw new Error('Forbidden: Admin access required');
55
+ }
56
+ return [req, res];
57
+ };
58
+ }
59
+ ```
60
+
61
+ ## See Also
62
+
63
+ - [LemonLDAP::NG Documentation](https://lemonldap-ng.org/documentation)
64
+ - [OpenID Connect Specification](https://openid.net/connect/)
65
+ - [express-openid-connect](https://github.com/auth0/express-openid-connect)
@@ -0,0 +1,95 @@
1
+ # CrowdSec Integration
2
+
3
+ IP reputation and blocking using [CrowdSec](https://crowdsec.net/).
4
+
5
+ ## Configuration
6
+
7
+ ```bash
8
+ --plugin core/auth/crowdsec \
9
+ --crowdsec-url "http://localhost:8080" \
10
+ --crowdsec-api-key "your-api-key"
11
+ ```
12
+
13
+ **Environment Variables:**
14
+
15
+ ```bash
16
+ DM_CROWDSEC_URL="http://localhost:8080"
17
+ DM_CROWDSEC_API_KEY="your-api-key"
18
+ ```
19
+
20
+ ## Prerequisites
21
+
22
+ 1. **CrowdSec Installation**: Running CrowdSec instance
23
+ 2. **API Key**: Bouncer API key from CrowdSec
24
+
25
+ ## How It Works
26
+
27
+ 1. Extracts client IP from request (respects trusted proxy)
28
+ 2. Queries CrowdSec API for IP reputation
29
+ 3. Blocks requests from banned IPs with `403 Forbidden`
30
+ 4. Allows legitimate requests to proceed
31
+
32
+ ## Use Cases
33
+
34
+ - **IP Reputation**: Block known malicious IPs
35
+ - **Threat Intelligence**: Leverage community-shared threat data
36
+ - **Dynamic Blocking**: Automatic response to attacks
37
+ - **Compliance**: Security monitoring and logging
38
+
39
+ ## CrowdSec Setup
40
+
41
+ ### Install CrowdSec
42
+
43
+ ```bash
44
+ # Debian/Ubuntu
45
+ curl -s https://packagecloud.io/install/repositories/crowdsec/crowdsec/script.deb.sh | sudo bash
46
+ sudo apt install crowdsec
47
+
48
+ # Generate bouncer API key
49
+ sudo cscli bouncers add ldap-rest-bouncer
50
+ ```
51
+
52
+ ### Configure LDAP-Rest
53
+
54
+ ```bash
55
+ npx ldap-rest \
56
+ --plugin core/auth/crowdsec \
57
+ --crowdsec-url "http://localhost:8080" \
58
+ --crowdsec-api-key "generated-api-key" \
59
+ ...
60
+ ```
61
+
62
+ ## Combining with Other Security Plugins
63
+
64
+ Recommended security stack:
65
+
66
+ ```bash
67
+ --plugin core/auth/trustedProxy \
68
+ --trusted-proxy "127.0.0.1" \
69
+ --plugin core/auth/crowdsec \
70
+ --crowdsec-url "http://localhost:8080" \
71
+ --crowdsec-api-key "your-api-key" \
72
+ --plugin core/auth/rateLimit \
73
+ --rate-limit-max 100 \
74
+ --plugin core/auth/token \
75
+ --auth-token "your-token"
76
+ ```
77
+
78
+ Order matters:
79
+
80
+ 1. `trustedProxy` - Sanitize IP headers first
81
+ 2. `crowdsec` - Block known bad IPs
82
+ 3. `rateLimit` - Limit request frequency
83
+ 4. Authentication plugins
84
+
85
+ ## Security Considerations
86
+
87
+ - Keep CrowdSec updated for latest threat intelligence
88
+ - Monitor CrowdSec logs for blocked requests
89
+ - Consider local decisions for sensitive applications
90
+ - Use HTTPS between LDAP-Rest and CrowdSec API
91
+
92
+ ## See Also
93
+
94
+ - [CrowdSec Documentation](https://docs.crowdsec.net/)
95
+ - [CrowdSec Hub](https://hub.crowdsec.net/)
@@ -0,0 +1,293 @@
1
+ # HMAC Authentication
2
+
3
+ HMAC-SHA256 request signing authentication for backend services (Registration Service, admin panel backend, cloudery, etc.).
4
+
5
+ ## Configuration
6
+
7
+ ### Basic Configuration
8
+
9
+ ```bash
10
+ --plugin core/auth/hmac \
11
+ --auth-hmac "registration-service:secret-key-minimum-32-chars:Registration Service" \
12
+ --auth-hmac "cloudery:another-secret-key-long-enough:Cloudery Backend"
13
+ ```
14
+
15
+ **Environment Variable:**
16
+
17
+ ```bash
18
+ DM_AUTH_HMAC="registration-service:secret-key-minimum-32-chars:Registration Service,cloudery:another-secret-key-long-enough:Cloudery Backend"
19
+ ```
20
+
21
+ **Syntax:** `service-id:secret:name`
22
+
23
+ - **service-id**: Service identifier (e.g., `registration-service`, `cloudery`)
24
+ - **secret**: Shared secret for HMAC (minimum 32 characters recommended)
25
+ - **name**: Descriptive service name (can contain colons)
26
+
27
+ ### Advanced Configuration
28
+
29
+ ```bash
30
+ --auth-hmac-window 120000 # Time window in milliseconds (default: 120000 = 2 minutes)
31
+ ```
32
+
33
+ **Environment Variable:**
34
+
35
+ ```bash
36
+ DM_AUTH_HMAC_WINDOW=120000 # Default: 120000ms (2 minutes)
37
+ ```
38
+
39
+ - **window**: Maximum time difference (in milliseconds) between server and client timestamp
40
+ - Prevents replay attacks by rejecting requests with timestamps outside the window
41
+
42
+ ## How It Works
43
+
44
+ ### Request Signing Process
45
+
46
+ 1. **Client calculates signature:**
47
+
48
+ ```
49
+ signature = HMAC-SHA256(
50
+ secret,
51
+ "METHOD|PATH|timestamp|body-hash"
52
+ )
53
+ ```
54
+
55
+ Where:
56
+ - `METHOD`: HTTP method (GET, POST, PATCH, DELETE, PUT, etc.)
57
+ - `PATH`: Request path with query string (e.g., `/api/v1/ldap/users?filter=active`)
58
+ - `timestamp`: Unix timestamp in milliseconds (e.g., `1698765432000`)
59
+ - `body-hash`: SHA256(request_body) for POST/PATCH/PUT, empty string for GET/DELETE/HEAD
60
+
61
+ 2. **Client sends Authorization header:**
62
+
63
+ ```
64
+ Authorization: HMAC-SHA256 service-id:timestamp:signature
65
+ ```
66
+
67
+ 3. **Server validates:**
68
+ - Extracts `service-id`, `timestamp`, and `signature` from header
69
+ - Verifies timestamp is within configured window (prevents replay attacks)
70
+ - Retrieves service secret using `service-id`
71
+ - Recalculates signature using same method
72
+ - Compares signatures using constant-time comparison (prevents timing attacks)
73
+ - Rejects if mismatch or timestamp expired
74
+
75
+ 4. **On success:**
76
+ - Sets `req.user` to service name
77
+ - Allows request to proceed
78
+
79
+ ## Usage
80
+
81
+ ### Manual Request Example
82
+
83
+ ```bash
84
+ # Example: GET request
85
+ SERVICE_ID="registration-service"
86
+ SECRET="secret-key-minimum-32-chars"
87
+ METHOD="GET"
88
+ PATH="/api/v1/ldap/users"
89
+ TIMESTAMP=$(date +%s000) # Unix timestamp in milliseconds
90
+
91
+ # Calculate body hash (empty for GET)
92
+ BODY_HASH=""
93
+
94
+ # Create signing string
95
+ SIGNING_STRING="${METHOD}|${PATH}|${TIMESTAMP}|${BODY_HASH}"
96
+
97
+ # Calculate HMAC-SHA256 signature
98
+ SIGNATURE=$(echo -n "$SIGNING_STRING" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2)
99
+
100
+ # Make request
101
+ curl -H "Authorization: HMAC-SHA256 ${SERVICE_ID}:${TIMESTAMP}:${SIGNATURE}" \
102
+ http://localhost:8081${PATH}
103
+ ```
104
+
105
+ ### POST Request with Body
106
+
107
+ ```bash
108
+ SERVICE_ID="registration-service"
109
+ SECRET="secret-key-minimum-32-chars"
110
+ METHOD="POST"
111
+ PATH="/api/v1/ldap/users"
112
+ TIMESTAMP=$(date +%s000)
113
+ BODY='{"uid":"user1","mail":"user1@example.com"}'
114
+
115
+ # Calculate body hash
116
+ BODY_HASH=$(echo -n "$BODY" | openssl dgst -sha256 | cut -d' ' -f2)
117
+
118
+ # Create signing string
119
+ SIGNING_STRING="${METHOD}|${PATH}|${TIMESTAMP}|${BODY_HASH}"
120
+
121
+ # Calculate signature
122
+ SIGNATURE=$(echo -n "$SIGNING_STRING" | openssl dgst -sha256 -hmac "$SECRET" | cut -d' ' -f2)
123
+
124
+ # Make request
125
+ curl -X POST \
126
+ -H "Authorization: HMAC-SHA256 ${SERVICE_ID}:${TIMESTAMP}:${SIGNATURE}" \
127
+ -H "Content-Type: application/json" \
128
+ -d "$BODY" \
129
+ http://localhost:8081${PATH}
130
+ ```
131
+
132
+ ### Browser Client
133
+
134
+ The HMAC client library is available as an npm module export:
135
+
136
+ ```bash
137
+ npm install ldap-rest
138
+ ```
139
+
140
+ ```typescript
141
+ import { HmacAuthClient } from 'ldap-rest/browser-shared-utils-hmac';
142
+
143
+ const client = new HmacAuthClient({
144
+ serviceId: 'registration-service',
145
+ secret: 'secret-key-minimum-32-chars',
146
+ });
147
+
148
+ // Automatic authentication with HMAC signature
149
+ const response = await client.get('/api/v1/ldap/users');
150
+ const users = await response.json();
151
+
152
+ // POST with automatic body hashing and signing
153
+ await client.post('/api/v1/ldap/users', {
154
+ uid: 'user1',
155
+ mail: 'user1@example.com',
156
+ });
157
+
158
+ // Other methods: put, patch, delete
159
+ await client.put('/api/v1/ldap/users/user1', { mail: 'new@example.com' });
160
+ await client.delete('/api/v1/ldap/users/user1');
161
+ ```
162
+
163
+ **Manual signature generation:**
164
+
165
+ ```typescript
166
+ import { generateHmacSignature } from 'ldap-rest/browser-shared-utils-hmac';
167
+
168
+ const signature = await generateHmacSignature(
169
+ 'secret-key-minimum-32-chars',
170
+ 'GET',
171
+ '/api/v1/ldap/users',
172
+ Date.now(),
173
+ undefined // no body for GET
174
+ );
175
+
176
+ const authHeader = `HMAC-SHA256 registration-service:${Date.now()}:${signature}`;
177
+ ```
178
+
179
+ ## Use Cases
180
+
181
+ - **Backend Services**: Service-to-service authentication (Registration Service, admin panels, etc.)
182
+ - **Microservices**: Secure inter-service communication
183
+ - **Webhooks**: Verify request authenticity and integrity
184
+ - **API Gateways**: Backend service authentication
185
+ - **Cloudery Integration**: Secure communication with cloudery backend
186
+ - **Automated Services**: CI/CD, monitoring, backup services
187
+
188
+ ## Security Considerations
189
+
190
+ - **Secret Strength**: Use secrets of at least 32 characters (64+ recommended)
191
+ - **Secret Storage**: Store secrets securely (encrypted configuration, environment variables, secret managers)
192
+ - **HTTPS Required**: Always use HTTPS to protect signatures in transit
193
+ - **Time Synchronization**: Ensure server and client clocks are synchronized (NTP recommended)
194
+ - **Replay Protection**: Time window prevents replay attacks (adjust `auth-hmac-window` as needed)
195
+ - **Constant-Time Comparison**: Signature validation uses `timingSafeEqual` to prevent timing attacks
196
+ - **Secret Rotation**: Rotate secrets periodically for enhanced security
197
+ - **Body Integrity**: Body hash ensures request payload hasn't been tampered with
198
+ - **Path Integrity**: Full path (including query parameters) is signed
199
+
200
+ ## Security Features
201
+
202
+ 1. **Replay Attack Prevention**: Timestamp validation with configurable window
203
+ 2. **Timing Attack Protection**: Constant-time signature comparison
204
+ 3. **Request Integrity**: Body hash ensures payload integrity
205
+ 4. **Path Integrity**: Query parameters included in signature
206
+ 5. **Multi-Service Support**: Isolated secrets per service
207
+ 6. **Clock Drift Tolerance**: Configurable time window (default 2 minutes)
208
+
209
+ ## Advantages Over Other Methods
210
+
211
+ | Feature | HMAC | Token | TOTP |
212
+ | ------------------------- | ---------------- | ----------- | ---------------- |
213
+ | **Request Integrity** | Yes (body hash) | No | No |
214
+ | **Replay Protection** | Yes (timestamp) | No | Yes (time-based) |
215
+ | **Signature Per Request** | Yes | No (static) | Yes (30s codes) |
216
+ | **Body Tampering Detect** | Yes | No | No |
217
+ | **Path/Query Protection** | Yes | No | No |
218
+ | **Setup Complexity** | Medium | Simple | Simple |
219
+ | **Best For** | Backend services | Simple APIs | MFA, user auth |
220
+
221
+ ## Comparison with Standards
222
+
223
+ This implementation is similar to:
224
+
225
+ - **AWS Signature V4**: Similar approach but simpler (AWS is more complex with canonicalization)
226
+ - **HTTP Message Signatures (RFC 9421)**: IETF standard for HTTP signatures
227
+ - **HMAC-Based Authentication**: Industry-standard pattern for service authentication
228
+
229
+ Our approach provides a good balance between security and simplicity:
230
+
231
+ - Simpler than AWS Signature V4 (easier to implement)
232
+ - More secure than static tokens (request-specific signatures)
233
+ - Better integrity than TOTP (includes body and path hashing)
234
+ - Standard cryptography (HMAC-SHA256)
235
+
236
+ ## Troubleshooting
237
+
238
+ **Problem:** 401 Unauthorized despite correct signature
239
+
240
+ **Solutions:**
241
+
242
+ 1. Verify service-id matches exactly (case-sensitive)
243
+ 2. Verify secret is correctly configured (minimum 32 characters)
244
+ 3. Check system clock synchronization (use NTP: `ntpdate -q pool.ntp.org`)
245
+ 4. Increase `--auth-hmac-window` if experiencing timing issues
246
+ 5. Verify Authorization header format: `HMAC-SHA256 service-id:timestamp:signature`
247
+ 6. Check server logs for specific error messages
248
+ 7. Ensure timestamp is in milliseconds, not seconds
249
+ 8. Verify body hash calculation (must match exactly)
250
+
251
+ **Problem:** Timestamp outside allowed window
252
+
253
+ **Solutions:**
254
+
255
+ 1. Synchronize clocks using NTP
256
+ 2. Increase `--auth-hmac-window` (default: 120000ms = 2 minutes)
257
+ 3. Check if timestamp is in milliseconds (not seconds)
258
+ 4. Verify both server and client are using same timezone reference (UTC)
259
+
260
+ **Problem:** Signature mismatch
261
+
262
+ **Solutions:**
263
+
264
+ 1. Verify signing string format: `METHOD|PATH|timestamp|body-hash`
265
+ 2. Ensure METHOD is uppercase (GET, POST, etc.)
266
+ 3. Include full path with query parameters
267
+ 4. For POST/PATCH/PUT: verify body hash is SHA256(JSON.stringify(body))
268
+ 5. For GET/DELETE/HEAD: body-hash must be empty string
269
+ 6. Ensure secret is exactly the same on client and server
270
+ 7. Use hex encoding for signature (lowercase)
271
+ 8. Check for trailing whitespace in secret
272
+
273
+ **Problem:** Warning about short secrets
274
+
275
+ **Solutions:**
276
+
277
+ 1. Use secrets of at least 32 characters
278
+ 2. Recommended: 64+ characters for enhanced security
279
+ 3. Generate secure random secrets:
280
+ ```bash
281
+ openssl rand -hex 32 # 64-character hex string
282
+ node -e "console.log(require('crypto').randomBytes(32).toString('hex'))"
283
+ ```
284
+
285
+ **Debug Example:**
286
+
287
+ ```bash
288
+ # Enable debug logging
289
+ DM_LOG_LEVEL=debug npm start
290
+
291
+ # Check signing string in logs
292
+ # Expected format: "GET|/api/v1/ldap/users|1698765432000|"
293
+ ```
@@ -0,0 +1,99 @@
1
+ # LemonLDAP::NG Authentication
2
+
3
+ Integration with [LemonLDAP::NG](https://lemonldap-ng.org/) (LLNG) Web SSO solution.
4
+
5
+ ## Configuration
6
+
7
+ ```bash
8
+ --plugin core/auth/llng \
9
+ --llng-ini /etc/lemonldap-ng/lemonldap-ng.ini
10
+ ```
11
+
12
+ **Environment Variable:**
13
+
14
+ ```bash
15
+ DM_LLNG_INI="/etc/lemonldap-ng/lemonldap-ng.ini"
16
+ ```
17
+
18
+ ## Prerequisites
19
+
20
+ 1. **LemonLDAP::NG Handler**: The `lemonldap-ng-handler` npm package (optional dependency)
21
+ 2. **LLNG Configuration**: Valid `lemonldap-ng.ini` file
22
+ 3. **Virtual Host Configuration**: LDAP-Rest must be configured as a protected application in LLNG
23
+
24
+ ## How It Works
25
+
26
+ 1. Uses the LemonLDAP::NG Handler to validate requests
27
+ 2. Extracts user identity from `Lm-Remote-User` header
28
+ 3. Sets `req.user` to authenticated username
29
+ 4. Inherits all LLNG authorization rules and features
30
+
31
+ ## Installation
32
+
33
+ Install the optional dependency:
34
+
35
+ ```bash
36
+ npm install lemonldap-ng-handler
37
+ ```
38
+
39
+ ## LLNG Configuration
40
+
41
+ Configure LDAP-Rest as a protected virtual host in LemonLDAP::NG:
42
+
43
+ ```apache
44
+ # In LLNG Manager: Virtual Hosts > api.example.com
45
+ <VirtualHost *:443>
46
+ ServerName api.example.com
47
+
48
+ # LemonLDAP::NG Handler
49
+ PerlHeaderParserHandler Lemonldap::NG::Handler::ApacheMP2
50
+
51
+ # Proxy to LDAP-Rest
52
+ ProxyPass / http://localhost:8081/
53
+ ProxyPassReverse / http://localhost:8081/
54
+ </VirtualHost>
55
+ ```
56
+
57
+ ## Use Cases
58
+
59
+ - **Enterprise SSO**: Centralized authentication for multiple applications
60
+ - **Advanced Authorization**: Fine-grained access control using LLNG rules
61
+ - **Session Management**: Centralized session handling
62
+ - **Multi-Factor Authentication**: MFA support through LLNG
63
+
64
+ ## Example: LLNG Authorization Rules
65
+
66
+ Configure access rules in LLNG Manager:
67
+
68
+ ```perl
69
+ # Allow only HR group to access users endpoint
70
+ $groups =~ /\bhr\b/ and $uri =~ m#^/api/v1/ldap/users#
71
+
72
+ # Allow admins full access
73
+ $groups =~ /\badmins\b/
74
+
75
+ # Allow specific users to manage groups
76
+ $uid eq "groupmanager" and $uri =~ m#^/api/v1/ldap/groups#
77
+ ```
78
+
79
+ ## Troubleshooting
80
+
81
+ **Problem:** Handler not found
82
+
83
+ **Solution:** Install optional dependency:
84
+
85
+ ```bash
86
+ npm install lemonldap-ng-handler
87
+ ```
88
+
89
+ **Problem:** Authentication refused
90
+
91
+ **Solutions:**
92
+
93
+ 1. Verify LLNG handler is configured correctly
94
+ 2. Check virtual host configuration
95
+ 3. Review LLNG access logs
96
+
97
+ ## See Also
98
+
99
+ - [LemonLDAP::NG Documentation](https://lemonldap-ng.org/documentation)