@@ -277,22 +277,25 @@ export class S3Renderer {
277277 const protectedPathAccess : CallExpression [ ] = [ ] ;
278278
279279 if ( accessPatterns . guest && accessPatterns . guest . length > 0 ) {
280- publicPathAccess . push ( this . createAllowPattern ( allowIdentifier , 'guest' , accessPatterns . guest ) ) ;
280+ publicPathAccess . push ( S3Renderer . createAllowPattern ( allowIdentifier , 'guest' , accessPatterns . guest ) ) ;
281281 }
282282 if ( accessPatterns . auth && accessPatterns . auth . length > 0 ) {
283283 // public/* is a shared path: authenticated users get the Gen1 auth permission set.
284- publicPathAccess . push ( this . createAllowPattern ( allowIdentifier , 'authenticated' , accessPatterns . auth ) ) ;
284+ publicPathAccess . push ( S3Renderer . createAllowPattern ( allowIdentifier , 'authenticated' , accessPatterns . auth ) ) ;
285285 // private/ and protected/ are per-user paths. Use allow.entity('identity') so the
286286 // {entity_id} token resolves to the caller's own Cognito identity, matching the
287287 // per-user scoping of the Gen1 configuration.
288- privatePathAccess . push ( this . createEntityPattern ( allowIdentifier , accessPatterns . auth ) ) ;
289- protectedPathAccess . push ( this . createEntityPattern ( allowIdentifier , accessPatterns . auth ) ) ;
290- // Gen1 protected/ also grants read to other authenticated users.
291- protectedPathAccess . push ( this . createAllowPattern ( allowIdentifier , 'authenticated' , [ 'read' ] ) ) ;
288+ privatePathAccess . push ( S3Renderer . createEntityPattern ( allowIdentifier , accessPatterns . auth ) ) ;
289+ protectedPathAccess . push ( S3Renderer . createEntityPattern ( allowIdentifier , accessPatterns . auth ) ) ;
290+ // Gen1 protected/ also grants read to other authenticated users. When the Gen1 auth
291+ // permission set is read-only, this authenticated read subsumes the owner's
292+ // entity('identity') read rule above; the overlap is harmless and keeps the per-path
293+ // mapping uniform across permission sets.
294+ protectedPathAccess . push ( S3Renderer . createAllowPattern ( allowIdentifier , 'authenticated' , [ 'read' ] ) ) ;
292295 }
293296 if ( accessPatterns . groups ) {
294297 for ( const [ groupName , permissions ] of Object . entries ( accessPatterns . groups ) ) {
295- const pattern = this . createAllowPattern ( allowIdentifier , `groups(['${ groupName } '])` , permissions ) ;
298+ const pattern = S3Renderer . createAllowPattern ( allowIdentifier , `groups(['${ groupName } '])` , permissions ) ;
296299 publicPathAccess . push ( pattern ) ;
297300 privatePathAccess . push ( pattern ) ;
298301 protectedPathAccess . push ( pattern ) ;
@@ -308,7 +311,7 @@ export class S3Renderer {
308311 }
309312 }
310313 for ( const [ functionName , permissions ] of Object . entries ( consolidated ) ) {
311- const pattern = this . createResourcePattern ( allowIdentifier , functionName , Array . from ( permissions ) ) ;
314+ const pattern = S3Renderer . createResourcePattern ( allowIdentifier , functionName , Array . from ( permissions ) ) ;
312315 publicPathAccess . push ( pattern ) ;
313316 privatePathAccess . push ( pattern ) ;
314317 protectedPathAccess . push ( pattern ) ;
@@ -349,7 +352,7 @@ export class S3Renderer {
349352 return factory . createPropertyAssignment ( factory . createIdentifier ( 'access' ) , accessFunction ) ;
350353 }
351354
352- private createAllowPattern ( allowIdentifier : ts . Identifier , userLevel : string , permissions : readonly Permission [ ] ) : CallExpression {
355+ private static createAllowPattern ( allowIdentifier : ts . Identifier , userLevel : string , permissions : readonly Permission [ ] ) : CallExpression {
353356 return factory . createCallExpression (
354357 factory . createPropertyAccessExpression ( allowIdentifier , factory . createIdentifier ( `${ userLevel } .to` ) ) ,
355358 undefined ,
@@ -361,7 +364,7 @@ export class S3Renderer {
361364 * Renders `allow.entity('identity').to([...])`, which scopes an {entity_id} path to the
362365 * caller's own Cognito identity in the generated IAM policy.
363366 */
364- private createEntityPattern ( allowIdentifier : ts . Identifier , permissions : readonly Permission [ ] ) : CallExpression {
367+ private static createEntityPattern ( allowIdentifier : ts . Identifier , permissions : readonly Permission [ ] ) : CallExpression {
365368 return factory . createCallExpression (
366369 factory . createPropertyAccessExpression (
367370 factory . createCallExpression (
@@ -376,7 +379,11 @@ export class S3Renderer {
376379 ) ;
377380 }
378381
379- private createResourcePattern ( allowIdentifier : ts . Identifier , functionName : string , permissions : readonly Permission [ ] ) : CallExpression {
382+ private static createResourcePattern (
383+ allowIdentifier : ts . Identifier ,
384+ functionName : string ,
385+ permissions : readonly Permission [ ] ,
386+ ) : CallExpression {
380387 return factory . createCallExpression (
381388 factory . createPropertyAccessExpression (
382389 factory . createCallExpression (
0 commit comments