{"record":{"id":"672b15d044f955bc","repo":"prestodb/presto","slug":"no-matching-aws-lake-formation-security-mapping","errorCode":null,"errorMessage":"No matching AWS Lake Formation Security Mapping","messagePattern":"No matching AWS Lake Formation Security Mapping","errorType":"http","errorClass":"AccessDeniedException","httpStatus":400,"severity":"error","filePath":"presto-hive-common/src/main/java/com/facebook/presto/hive/aws/security/AWSSecurityMappings.java","lineNumber":46,"sourceCode":"{\n    private final List<AWSSecurityMapping> awsSecurityMappings;\n\n    @JsonCreator\n    public AWSSecurityMappings(@JsonProperty(\"mappings\") List<AWSSecurityMapping> awsSecurityMappings)\n    {\n        checkArgument(awsSecurityMappings != null, \"No AWS Security mappings configured\");\n\n        this.awsSecurityMappings = ImmutableList.copyOf(awsSecurityMappings);\n    }\n\n    public AWSSecurityMapping getAWSLakeFormationSecurityMapping(String user)\n    {\n        Optional<AWSSecurityMapping> awsSecurityMapping = awsSecurityMappings.stream()\n                .filter(mapping -> (mapping.matches(user)))\n                .findFirst();\n\n        if (!awsSecurityMapping.isPresent()) {\n            throw new AccessDeniedException(\"No matching AWS Lake Formation Security Mapping\");\n        }\n\n        verify(!awsSecurityMapping.get().getCredentials().isPresent(),\n                \"Basic AWS Credentials are not supported for AWS Lake Formation Security Mapping\");\n\n        verify(awsSecurityMapping.get().getIamRole().isPresent(),\n                \"iamRole is mandatory for AWS Lake Formation Security Mapping\");\n\n        return awsSecurityMapping.get();\n    }\n\n    public AWSSecurityMapping getAWSS3SecurityMapping(String user)\n    {\n        Optional<AWSSecurityMapping> awsSecurityMapping = awsSecurityMappings.stream()\n                .filter(mapping -> mapping.matches(user))\n                .findFirst();\n\n        return awsSecurityMapping.orElseThrow(() -> new AccessDeniedException(\"No matching AWS S3 Security Mapping\"));","sourceCodeStart":28,"sourceCodeEnd":64,"githubUrl":"https://github.com/prestodb/presto/blob/55bb57d202de3b926896fa966c2c4a44c779634e/presto-hive-common/src/main/java/com/facebook/presto/hive/aws/security/AWSSecurityMappings.java#L28-L64","documentation":"AWSSecurityMappings.getAWSLakeFormationSecurityMapping finds the first security mapping whose user-access expression matches the requesting user. If no mapping matches, it throws AccessDeniedException('No matching AWS Lake Formation Security Mapping'), denying Lake Formation access for that principal. It is the Lake Formation equivalent of 'no IAM role mapping found for this user'.","triggerScenarios":"A query/principal accesses a Lake Formation-governed table while aws security-mapping entries' user-access regexes match no user; also thrown for a matching mapping that wrongly defines basic credentials or lacks an IAM role (the verify() calls right after).","commonSituations":"New user/group not covered by existing mapping patterns; typo in user-access regex; case-sensitivity mismatch; IAM role omitted from the mapping entry; Lake Formation enabled in catalog config but mappings file not updated after onboarding teams.","solutions":["Add or fix a security-mapping entry whose user-access expression matches the requesting principal, with an iam-role configured.","Test the regex against the exact user string (it is case-sensitive); adjust the pattern.","Ensure the matched mapping has an IAM role and no basic AWS credentials (both are enforced after the match).","Review presto-log for the actual user identity passed in — it may include a realm/ARN prefix your pattern doesn't cover."],"exampleFix":"// before (security mapping JSON)\n{\"userAccess\": \"^alice$\", \"iamRole\": \"arn:aws:iam::123:role/lf\"}\n// after\n{\"userAccess\": \"^(alice|bob)$\", \"iamRole\": \"arn:aws:iam::123:role/lf\"}\n","handlingStrategy":"validation","validationCode":"Optional<AWSSecurityMapping> m = securityMappings.stream()\n    .filter(x -> x.matches(currentUser))\n    .findFirst();\nif (!m.isPresent() || !m.get().getIamRole().isPresent()) {\n    throw new AccessDeniedException(\"user not mapped to a Lake Formation role: \" + currentUser);\n}","typeGuard":null,"tryCatchPattern":"try {\n    mapping = awsSecurityMappings.getAWSLakeFormationSecurityMapping(user);\n} catch (AccessDeniedException e) {\n    // return clear 403-style error to client with guidance to contact admin\n}","preventionTips":["Maintain a default/catch-all mapping or explicit onboarding step for new users/groups.","Test mapping regexes against exact principal strings (case-sensitive).","Always include iam-role in Lake Formation mappings; never basic credentials.","Log the effective user identity used for matching to debug pattern misses."],"tags":["aws","lakeformation","security-mapping","access-denied"],"backgroundTag":"no-matching-security-mapping","analyzedSha":"55bb57d202de3b926896fa966c2c4a44c779634e","analyzedAt":"2026-09-04T12:50:26.162Z","contentChangedAt":"2026-09-04T12:50:26.162Z","schemaVersion":2},"datasetVersion":"2026-09-11T21:17:09.523Z"}