diff --git a/Dockerfile b/Dockerfile
index ee42ad1..c49ccf8 100644
--- a/Dockerfile
+++ b/Dockerfile
@@ -1,4 +1,4 @@
-#syntax=docker/dockerfile:1.1-experimental
+#syntax=docker/dockerfile:1.2
 
 FROM node:12 AS deps
 WORKDIR /src
diff --git a/README.md b/README.md
index a159c15..1d32e94 100644
--- a/README.md
+++ b/README.md
@@ -471,9 +471,6 @@ using [actions/cache](https://github.com/actions/cache) with this action:
   ```
 </details>
 
-> If you want to [export layers for all stages](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue),
-> you have to specify `mode=max` attribute in `cache-to`.
-
 ### Handle tags and labels
 
 If you come from [`v1`](https://github.com/docker/build-push-action/tree/releases/v1#readme) and want an
@@ -622,7 +619,8 @@ Following inputs can be used as `step.with` keys
 | `outputs`           | List     | List of [output destinations](https://github.com/docker/buildx#-o---outputpath-typetypekeyvalue) (format: `type=local,dest=path`) |
 | `cache-from`        | List     | List of [external cache sources](https://github.com/docker/buildx#--cache-fromnametypetypekeyvalue) (eg. `type=local,src=path/to/dir`) |
 | `cache-to`          | List     | List of [cache export destinations](https://github.com/docker/buildx#--cache-tonametypetypekeyvalue) (eg. `type=local,dest=path/to/dir`) |
-| `secrets`           | List     | List of secrets to expose to the build (eg. `key=value`, `GIT_AUTH_TOKEN=mytoken`) |
+| `secrets`           | List     | List of secrets to expose to the build (eg. `key=string`, `GIT_AUTH_TOKEN=mytoken`) |
+| `secret-files`      | List     | List of secret files to expose to the build (eg. `key=filename`, `MY_SECRET=./secret.txt`) |
 | `ssh`               | List     | List of SSH agent socket or keys to expose to the build |
 
 ### outputs
diff --git a/__tests__/buildx.test.ts b/__tests__/buildx.test.ts
index 9c8a16e..741e29c 100644
--- a/__tests__/buildx.test.ts
+++ b/__tests__/buildx.test.ts
@@ -119,21 +119,34 @@ describe('parseVersion', () => {
 
 describe('getSecret', () => {
   test.each([
-    ['A_SECRET=abcdef0123456789', 'A_SECRET', 'abcdef0123456789', false],
-    ['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false],
-    ['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false],
-    ['aaaaaaaa', '', '', true],
-    ['aaaaaaaa=', '', '', true],
-    ['=bbbbbbb', '', '', true]
-  ])('given %p key and %p secret', async (kvp, key, secret, invalid) => {
+    ['A_SECRET=abcdef0123456789', false, 'A_SECRET', 'abcdef0123456789', false],
+    ['GIT_AUTH_TOKEN=abcdefghijklmno=0123456789', false, 'GIT_AUTH_TOKEN', 'abcdefghijklmno=0123456789', false],
+    ['MY_KEY=c3RyaW5nLXdpdGgtZXF1YWxzCg==', false, 'MY_KEY', 'c3RyaW5nLXdpdGgtZXF1YWxzCg==', false],
+    ['aaaaaaaa', false, '', '', true],
+    ['aaaaaaaa=', false, '', '', true],
+    ['=bbbbbbb', false, '', '', true],
+    [
+      `foo=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`,
+      true,
+      'foo',
+      'bar',
+      false
+    ],
+    [`notfound=secret`, true, '', '', true]
+  ])('given %p key and %p secret', async (kvp, file, exKey, exValue, invalid) => {
     try {
-      const secretArgs = await buildx.getSecret(kvp);
+      let secret: string;
+      if (file) {
+        secret = await buildx.getSecretFile(kvp);
+      } else {
+        secret = await buildx.getSecretString(kvp);
+      }
       expect(true).toBe(!invalid);
-      console.log(`secretArgs: ${secretArgs}`);
-      expect(secretArgs).toEqual(`id=${key},src=${tmpNameSync}`);
-      const secretContent = await fs.readFileSync(tmpNameSync, 'utf-8');
-      console.log(`secretValue: ${secretContent}`);
-      expect(secretContent).toEqual(secret);
+      console.log(`secret: ${secret}`);
+      expect(secret).toEqual(`id=${exKey},src=${tmpNameSync}`);
+      const secretValue = await fs.readFileSync(tmpNameSync, 'utf-8');
+      console.log(`secretValue: ${secretValue}`);
+      expect(secretValue).toEqual(exValue);
     } catch (err) {
       expect(true).toBe(invalid);
     }
diff --git a/__tests__/context.test.ts b/__tests__/context.test.ts
index 8e5dae2..a3e3e0d 100644
--- a/__tests__/context.test.ts
+++ b/__tests__/context.test.ts
@@ -337,6 +337,27 @@ ccc`],
         '--push',
         'https://github.com/docker/build-push-action.git#heads/master'
       ]
+    ],
+    [
+      '0.5.1',
+      new Map<string, string>([
+        ['context', 'https://github.com/docker/build-push-action.git#heads/master'],
+        ['tag', 'localhost:5000/name/app:latest'],
+        ['secret-files', `MY_SECRET=${path.join(__dirname, 'fixtures', 'secret.txt').split(path.sep).join(path.posix.sep)}`],
+        ['file', './test/Dockerfile'],
+        ['builder', 'builder-git-context-2'],
+        ['push', 'true']
+      ]),
+      [
+        'buildx',
+        'build',
+        '--iidfile', '/tmp/.docker-build-push-jest/iidfile',
+        '--secret', 'id=MY_SECRET,src=/tmp/.docker-build-push-jest/.tmpname-jest',
+        '--file', './test/Dockerfile',
+        '--builder', 'builder-git-context-2',
+        '--push',
+        'https://github.com/docker/build-push-action.git#heads/master'
+      ]
     ]
   ])(
     'given %p with %p as inputs, returns %p',
diff --git a/__tests__/fixtures/secret.txt b/__tests__/fixtures/secret.txt
new file mode 100644
index 0000000..ba0e162
--- /dev/null
+++ b/__tests__/fixtures/secret.txt
@@ -0,0 +1 @@
+bar
\ No newline at end of file
diff --git a/dist/index.js b/dist/index.js
index 67f1095..aa03314 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -4581,7 +4581,7 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
     return (mod && mod.__esModule) ? mod : { "default": mod };
 };
 Object.defineProperty(exports, "__esModule", { value: true });
-exports.parseVersion = exports.getVersion = exports.isAvailable = exports.hasGitAuthToken = exports.isLocalOrTarExporter = exports.getSecret = exports.getImageID = exports.getImageIDFile = void 0;
+exports.parseVersion = exports.getVersion = exports.isAvailable = exports.hasGitAuthToken = exports.isLocalOrTarExporter = exports.getSecret = exports.getSecretFile = exports.getSecretString = exports.getImageID = exports.getImageIDFile = void 0;
 const sync_1 = __importDefault(__webpack_require__(750));
 const fs_1 = __importDefault(__webpack_require__(747));
 const path_1 = __importDefault(__webpack_require__(622));
@@ -4604,18 +4604,36 @@ function getImageID() {
     });
 }
 exports.getImageID = getImageID;
-function getSecret(kvp) {
+function getSecretString(kvp) {
+    return __awaiter(this, void 0, void 0, function* () {
+        return getSecret(kvp, false);
+    });
+}
+exports.getSecretString = getSecretString;
+function getSecretFile(kvp) {
+    return __awaiter(this, void 0, void 0, function* () {
+        return getSecret(kvp, true);
+    });
+}
+exports.getSecretFile = getSecretFile;
+function getSecret(kvp, file) {
     return __awaiter(this, void 0, void 0, function* () {
         const delimiterIndex = kvp.indexOf('=');
         const key = kvp.substring(0, delimiterIndex);
-        const value = kvp.substring(delimiterIndex + 1);
+        let value = kvp.substring(delimiterIndex + 1);
         if (key.length == 0 || value.length == 0) {
             throw new Error(`${kvp} is not a valid secret`);
         }
+        if (file) {
+            if (!fs_1.default.existsSync(value)) {
+                throw new Error(`secret file ${value} not found`);
+            }
+            value = fs_1.default.readFileSync(value, { encoding: 'utf-8' });
+        }
         const secretFile = context.tmpNameSync({
             tmpdir: context.tmpDir()
         });
-        yield fs_1.default.writeFileSync(secretFile, value);
+        fs_1.default.writeFileSync(secretFile, value);
         return `id=${key},src=${secretFile}`;
     });
 }
@@ -13003,6 +13021,7 @@ function getInputs(defaultContext) {
             cacheFrom: yield getInputList('cache-from', true),
             cacheTo: yield getInputList('cache-to', true),
             secrets: yield getInputList('secrets', true),
+            secretFiles: yield getInputList('secret-files', true),
             githubToken: core.getInput('github-token'),
             ssh: yield getInputList('ssh')
         };
@@ -13055,14 +13074,22 @@ function getBuildArgs(inputs, defaultContext, buildxVersion) {
         }));
         yield exports.asyncForEach(inputs.secrets, (secret) => __awaiter(this, void 0, void 0, function* () {
             try {
-                args.push('--secret', yield buildx.getSecret(secret));
+                args.push('--secret', yield buildx.getSecretString(secret));
+            }
+            catch (err) {
+                core.warning(err.message);
+            }
+        }));
+        yield exports.asyncForEach(inputs.secretFiles, (secretFile) => __awaiter(this, void 0, void 0, function* () {
+            try {
+                args.push('--secret', yield buildx.getSecretFile(secretFile));
             }
             catch (err) {
                 core.warning(err.message);
             }
         }));
         if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) {
-            args.push('--secret', yield buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
+            args.push('--secret', yield buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
         }
         yield exports.asyncForEach(inputs.ssh, (ssh) => __awaiter(this, void 0, void 0, function* () {
             args.push('--ssh', ssh);
diff --git a/src/buildx.ts b/src/buildx.ts
index 36fbc14..327604a 100644
--- a/src/buildx.ts
+++ b/src/buildx.ts
@@ -18,17 +18,34 @@ export async function getImageID(): Promise<string | undefined> {
   return fs.readFileSync(iidFile, {encoding: 'utf-8'});
 }
 
-export async function getSecret(kvp: string): Promise<string> {
+export async function getSecretString(kvp: string): Promise<string> {
+  return getSecret(kvp, false);
+}
+
+export async function getSecretFile(kvp: string): Promise<string> {
+  return getSecret(kvp, true);
+}
+
+export async function getSecret(kvp: string, file: boolean): Promise<string> {
   const delimiterIndex = kvp.indexOf('=');
   const key = kvp.substring(0, delimiterIndex);
-  const value = kvp.substring(delimiterIndex + 1);
+  let value = kvp.substring(delimiterIndex + 1);
   if (key.length == 0 || value.length == 0) {
     throw new Error(`${kvp} is not a valid secret`);
   }
+
+  if (file) {
+    if (!fs.existsSync(value)) {
+      throw new Error(`secret file ${value} not found`);
+    }
+    value = fs.readFileSync(value, {encoding: 'utf-8'});
+  }
+
   const secretFile = context.tmpNameSync({
     tmpdir: context.tmpDir()
   });
-  await fs.writeFileSync(secretFile, value);
+  fs.writeFileSync(secretFile, value);
+
   return `id=${key},src=${secretFile}`;
 }
 
diff --git a/src/context.ts b/src/context.ts
index 4608354..9b81fdd 100644
--- a/src/context.ts
+++ b/src/context.ts
@@ -30,6 +30,7 @@ export interface Inputs {
   cacheFrom: string[];
   cacheTo: string[];
   secrets: string[];
+  secretFiles: string[];
   githubToken: string;
   ssh: string[];
 }
@@ -73,6 +74,7 @@ export async function getInputs(defaultContext: string): Promise<Inputs> {
     cacheFrom: await getInputList('cache-from', true),
     cacheTo: await getInputList('cache-to', true),
     secrets: await getInputList('secrets', true),
+    secretFiles: await getInputList('secret-files', true),
     githubToken: core.getInput('github-token'),
     ssh: await getInputList('ssh')
   };
@@ -123,13 +125,20 @@ async function getBuildArgs(inputs: Inputs, defaultContext: string, buildxVersio
   });
   await asyncForEach(inputs.secrets, async secret => {
     try {
-      args.push('--secret', await buildx.getSecret(secret));
+      args.push('--secret', await buildx.getSecretString(secret));
+    } catch (err) {
+      core.warning(err.message);
+    }
+  });
+  await asyncForEach(inputs.secretFiles, async secretFile => {
+    try {
+      args.push('--secret', await buildx.getSecretFile(secretFile));
     } catch (err) {
       core.warning(err.message);
     }
   });
   if (inputs.githubToken && !buildx.hasGitAuthToken(inputs.secrets) && inputs.context == defaultContext) {
-    args.push('--secret', await buildx.getSecret(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
+    args.push('--secret', await buildx.getSecretString(`GIT_AUTH_TOKEN=${inputs.githubToken}`));
   }
   await asyncForEach(inputs.ssh, async ssh => {
     args.push('--ssh', ssh);