Skip to content

Commit b548426

Browse files
committed
CLDSRV-755: support flexible ARN matching for service user authorization
Add support for partial ARN prefix matching in isRateLimitServiceUser to allow more flexible configuration options: - Full ARN match: Exact user verification - Account-only match: Any user from management account - Path prefix match: Any user under specific path This allows operators to configure rate limiting with different levels of specificity while maintaining security through timing-safe comparisons. Example configurations: serviceUserArn: "arn:aws:iam::000000000000" (account only) serviceUserArn: "arn:aws:iam::000000000000:user/scality-internal/service-s3-ratelimit" (specific user)
1 parent 6f489d3 commit b548426

File tree

1 file changed

+27
-3
lines changed

1 file changed

+27
-3
lines changed

lib/api/apiUtils/authorization/serviceUser.js

Lines changed: 27 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,34 @@ const { timingSafeEqual } = require('crypto');
22

33
const { config } = require('../../../Config');
44

5-
function isRateLimitServiceUser(authInfo) {
5+
function isRateLimitServiceUser(authInfo, log) {
66
try {
7-
return timingSafeEqual(Buffer.from(authInfo.getArn()), Buffer.from(config.rateLimiting.serviceUserArn));
8-
} catch {
7+
const requestArn = authInfo.getArn();
8+
const configuredArn = config.rateLimiting?.serviceUserArn;
9+
10+
if (!configuredArn) {
11+
log.warn('Access denied - no configured ARN under rateLimiting.serviceUserArn', { requestArn });
12+
return false;
13+
}
14+
15+
// Support partial ARN matching (e.g., match by account only)
16+
// If configuredArn is shorter, do prefix match; otherwise exact match
17+
let match;
18+
if (requestArn.length >= configuredArn.length) {
19+
// Extract prefix from requestArn to match configuredArn length
20+
const requestPrefix = requestArn.substring(0, configuredArn.length);
21+
match = timingSafeEqual(
22+
Buffer.from(requestPrefix),
23+
Buffer.from(configuredArn)
24+
);
25+
} else {
26+
// requestArn is shorter than configured - no match
27+
log.warn('Access denied - request ARN is shorter than configured ARN', { requestArn, configuredArn });
28+
match = false;
29+
}
30+
return match;
31+
} catch (err) {
32+
log.error('Error checking if request is rate limit service user', { error: err });
933
return false;
1034
}
1135
}

0 commit comments

Comments
 (0)