in polaris-core/src/main/java/org/apache/polaris/core/storage/aws/AwsCredentialsStorageIntegration.java [116:189]
private IamPolicy policyString(
String roleArn, boolean allowList, Set<String> readLocations, Set<String> writeLocations) {
IamPolicy.Builder policyBuilder = IamPolicy.builder();
IamStatement.Builder allowGetObjectStatementBuilder =
IamStatement.builder()
.effect(IamEffect.ALLOW)
.addAction("s3:GetObject")
.addAction("s3:GetObjectVersion");
Map<String, IamStatement.Builder> bucketListStatementBuilder = new HashMap<>();
Map<String, IamStatement.Builder> bucketGetLocationStatementBuilder = new HashMap<>();
String arnPrefix = getArnPrefixFor(roleArn);
Stream.concat(readLocations.stream(), writeLocations.stream())
.distinct()
.forEach(
location -> {
URI uri = URI.create(location);
allowGetObjectStatementBuilder.addResource(
IamResource.create(
arnPrefix + StorageUtil.concatFilePrefixes(parseS3Path(uri), "*", "/")));
final var bucket = arnPrefix + StorageUtil.getBucket(uri);
if (allowList) {
bucketListStatementBuilder
.computeIfAbsent(
bucket,
(String key) ->
IamStatement.builder()
.effect(IamEffect.ALLOW)
.addAction("s3:ListBucket")
.addResource(key))
.addCondition(
IamConditionOperator.STRING_LIKE,
"s3:prefix",
StorageUtil.concatFilePrefixes(trimLeadingSlash(uri.getPath()), "*", "/"));
}
bucketGetLocationStatementBuilder.computeIfAbsent(
bucket,
key ->
IamStatement.builder()
.effect(IamEffect.ALLOW)
.addAction("s3:GetBucketLocation")
.addResource(key));
});
if (!writeLocations.isEmpty()) {
IamStatement.Builder allowPutObjectStatementBuilder =
IamStatement.builder()
.effect(IamEffect.ALLOW)
.addAction("s3:PutObject")
.addAction("s3:DeleteObject");
writeLocations.forEach(
location -> {
URI uri = URI.create(location);
allowPutObjectStatementBuilder.addResource(
IamResource.create(
arnPrefix + StorageUtil.concatFilePrefixes(parseS3Path(uri), "*", "/")));
});
policyBuilder.addStatement(allowPutObjectStatementBuilder.build());
}
if (!bucketListStatementBuilder.isEmpty()) {
bucketListStatementBuilder
.values()
.forEach(statementBuilder -> policyBuilder.addStatement(statementBuilder.build()));
} else if (allowList) {
// add list privilege with 0 resources
policyBuilder.addStatement(
IamStatement.builder().effect(IamEffect.ALLOW).addAction("s3:ListBucket").build());
}
bucketGetLocationStatementBuilder
.values()
.forEach(statementBuilder -> policyBuilder.addStatement(statementBuilder.build()));
return policyBuilder.addStatement(allowGetObjectStatementBuilder.build()).build();
}