diff --git a/packages/fs-aws/src/credentials.ts b/packages/fs-aws/src/credentials.ts
index b5cfeecf..936994af 100644
--- a/packages/fs-aws/src/credentials.ts
+++ b/packages/fs-aws/src/credentials.ts
@@ -1,6 +1,6 @@
 import { S3Client } from '@aws-sdk/client-s3';
 import { fromTemporaryCredentials } from '@aws-sdk/credential-providers';
-import { FileSystem, FileSystemProvider } from '@chunkd/fs';
+import { FileSystem, FileSystemProvider, Flag } from '@chunkd/fs';
 
 import { FsAwsS3 } from './fs.s3.js';
 import { AwsCredentialConfig, AwsCredentialProvider } from './types.js';
@@ -18,6 +18,12 @@ export function validateConfig(cfg: AwsCredentialProvider, loc: URL): AwsCredent
   return cfg;
 }
 
+function credentialsMatch(cfg: AwsCredentialConfig, href: string, flag: Flag): boolean {
+  if (!href.startsWith(cfg.prefix)) return false;
+  if (flag === 'rw' && cfg.flags === 'r') return false;
+  return true;
+}
+
 export class FsConfigFetcher {
   loc: URL;
   fs: FileSystem;
@@ -39,11 +45,11 @@ export class FsConfigFetcher {
     return this._config;
   }
 
-  async findCredentials(loc: URL): Promise<AwsCredentialConfig | null> {
+  async findCredentials(loc: URL, flag: Flag): Promise<AwsCredentialConfig | null> {
     const href = loc.href;
     const cfg = await this.config;
     for (const credentials of cfg.prefixes) {
-      if (href.startsWith(credentials.prefix)) return credentials;
+      if (credentialsMatch(credentials, href, flag)) return credentials;
     }
     return null;
   }
@@ -147,21 +153,23 @@ export class AwsS3CredentialProvider implements FileSystemProvider<FsAwsS3> {
   }
 
   /** Look up the credentials for a path */
-  async findCredentials(loc: URL): Promise<AwsCredentialConfig | null> {
+  async findCredentials(loc: URL, flag: Flag): Promise<AwsCredentialConfig | null> {
     const href = loc.href;
     for (const cfg of this.configs) {
       if ('findCredentials' in cfg) {
-        const credentials = await cfg.findCredentials(loc);
+        const credentials = await cfg.findCredentials(loc, flag);
         if (credentials) return credentials;
       } else if (href.startsWith(cfg.prefix)) {
+        // If we need write credentials but these credentials only provide read skip it
+        if (flag === 'rw' && cfg.flags === 'r') continue;
         return cfg;
       }
     }
     return null;
   }
 
-  async find(path: URL): Promise<FsAwsS3 | null> {
-    const cs = await this.findCredentials(path);
+  async find(loc: URL, flag: Flag): Promise<FsAwsS3 | null> {
+    const cs = await this.findCredentials(loc, flag);
     if (cs == null) return null;
 
     const cacheKey = `${cs.roleArn}__${cs.externalId}__${cs.roleSessionDuration}`;
diff --git a/packages/fs-aws/src/fs.s3.ts b/packages/fs-aws/src/fs.s3.ts
index bc7588de..ce095307 100644
--- a/packages/fs-aws/src/fs.s3.ts
+++ b/packages/fs-aws/src/fs.s3.ts
@@ -130,7 +130,7 @@ export class FsAwsS3 implements FileSystem {
       const ce = toFsError(e, `Failed to list: "${loc}"`, loc, 'list', this);
 
       if (this.credentials != null && ce.code === 403) {
-        const newFs = await this.credentials.find(loc);
+        const newFs = await this.credentials.find(loc, 'r');
         if (newFs) {
           yield* newFs.details(loc, opts);
           return;
@@ -154,7 +154,7 @@ export class FsAwsS3 implements FileSystem {
     } catch (e) {
       const ce = toFsError(e, `Failed to read: "${loc}"`, loc, 'read', this);
       if (this.credentials != null && ce.code === 403) {
-        const newFs = await this.credentials.find(loc);
+        const newFs = await this.credentials.find(loc, 'r');
         if (newFs) return newFs.read(loc);
       }
       throw ce;
@@ -185,7 +185,7 @@ export class FsAwsS3 implements FileSystem {
     } catch (e) {
       const ce = toFsError(e, `Failed to write to "${loc}"`, loc, 'write', this);
       if (ce.code === 403) {
-        const newFs = await this.credentials.find(testPath);
+        const newFs = await this.credentials.find(testPath, 'rw');
         if (newFs) return newFs;
       }
       throw ce;
@@ -222,7 +222,7 @@ export class FsAwsS3 implements FileSystem {
     } catch (e) {
       const ce = toFsError(e, `Failed to write: "${loc}"`, loc, 'write', this);
       if (this.credentials != null && ce.code === 403) {
-        const newFs = await this.credentials.find(loc);
+        const newFs = await this.credentials.find(loc, 'rw');
         if (newFs) return newFs.write(loc, buf, ctx);
       }
       throw ce;
@@ -243,7 +243,7 @@ export class FsAwsS3 implements FileSystem {
       const ce = toFsError(e, `Failed to delete: "${loc}"`, loc, 'delete', this);
       if (ce.code === 404) return;
       if (this.credentials != null && ce.code === 403) {
-        const newFs = await this.credentials.find(loc);
+        const newFs = await this.credentials.find(loc, 'rw');
         if (newFs) return newFs.delete(loc);
       }
       throw ce;
@@ -297,7 +297,7 @@ export class FsAwsS3 implements FileSystem {
       if (ce.code === 404) return null;
 
       if (this.credentials != null && ce.code === 403) {
-        const newFs = await this.credentials.find(loc);
+        const newFs = await this.credentials.find(loc, 'r');
         if (newFs) return newFs.head(loc);
       }
       throw ce;
diff --git a/packages/fs/src/flags.ts b/packages/fs/src/flags.ts
index 6f5dd1dc..24a1d1e3 100644
--- a/packages/fs/src/flags.ts
+++ b/packages/fs/src/flags.ts
@@ -1,3 +1,5 @@
 export type Flag = FlagRead | FlagReadWrite;
+/** Ability to read from a location */
 export type FlagRead = 'r';
+/** Ability to read and write to a location */
 export type FlagReadWrite = 'rw';
diff --git a/packages/fs/src/provider.ts b/packages/fs/src/provider.ts
index 38ddfe08..89de7fe5 100644
--- a/packages/fs/src/provider.ts
+++ b/packages/fs/src/provider.ts
@@ -1,6 +1,14 @@
 import { FileSystem } from './file.system.js';
+import { Flag } from './flags.js';
 
 export interface FileSystemProvider<T extends FileSystem = FileSystem> {
-  /** find a file system for a given prefix  */
-  find(prefix: URL): Promise<T | null>;
+  /**
+   * find a file system for a given prefix and permissions
+   *
+   * @param prefix location to search for
+   * @param flag Permissions required (Read or ReadWrite)
+   *
+   * @returns File System with the required permission, null otherwise
+   */
+  find(prefix: URL, flag: Flag): Promise<T | null>;
 }