diff --git a/__tests__/actionUtils.test.ts b/__tests__/actionUtils.test.ts
index f46d65d..01ccff3 100644
--- a/__tests__/actionUtils.test.ts
+++ b/__tests__/actionUtils.test.ts
@@ -1,5 +1,4 @@
 import * as core from "@actions/core";
-import * as os from "os";
 import * as path from "path";
 
 import { Events, Outputs, State } from "../src/constants";
@@ -181,42 +180,6 @@ test("isValidEvent returns false for unknown event", () => {
     expect(isValidEvent).toBe(false);
 });
 
-test("resolvePath with no ~ in path", () => {
-    const filePath = ".cache/yarn";
-
-    const resolvedPath = actionUtils.resolvePath(filePath);
-
-    const expectedPath = path.resolve(filePath);
-    expect(resolvedPath).toBe(expectedPath);
-});
-
-test("resolvePath with ~ in path", () => {
-    const filePath = "~/.cache/yarn";
-
-    const homedir = jest.requireActual("os").homedir();
-    const homedirMock = jest.spyOn(os, "homedir");
-    homedirMock.mockImplementation(() => {
-        return homedir;
-    });
-
-    const resolvedPath = actionUtils.resolvePath(filePath);
-
-    const expectedPath = path.join(homedir, ".cache/yarn");
-    expect(resolvedPath).toBe(expectedPath);
-});
-
-test("resolvePath with home not found", () => {
-    const filePath = "~/.cache/yarn";
-    const homedirMock = jest.spyOn(os, "homedir");
-    homedirMock.mockImplementation(() => {
-        return "";
-    });
-
-    expect(() => actionUtils.resolvePath(filePath)).toThrow(
-        "Unable to resolve `~` to HOME"
-    );
-});
-
 test("isValidEvent returns true for push event", () => {
     const event = Events.Push;
     process.env[Events.Key] = event;
diff --git a/__tests__/pathUtils.test.ts b/__tests__/pathUtils.test.ts
new file mode 100644
index 0000000..59f6ec7
--- /dev/null
+++ b/__tests__/pathUtils.test.ts
@@ -0,0 +1,42 @@
+import * as path from "path";
+import * as os from "os";
+import * as pathUtils from "../src/utils/pathUtils";
+
+jest.mock("@actions/core");
+jest.mock("os");
+
+test("expandPaths with no ~ in path", () => {
+    const filePath = ".cache/yarn";
+
+    const resolvedPath = pathUtils.expandPaths([filePath]);
+
+    const expectedPath = [path.resolve(filePath)];
+    expect(resolvedPath).toStrictEqual(expectedPath);
+});
+
+test("expandPaths with ~ in path", () => {
+    const filePath = "~/.cache/yarn";
+
+    const homedir = jest.requireActual("os").homedir();
+    const homedirMock = jest.spyOn(os, "homedir");
+    homedirMock.mockImplementation(() => {
+        return homedir;
+    });
+
+    const resolvedPath = pathUtils.expandPaths([filePath]);
+
+    const expectedPath = [path.join(homedir, ".cache/yarn")];
+    expect(resolvedPath).toStrictEqual(expectedPath);
+});
+
+test("expandPaths with home not found", () => {
+    const filePath = "~/.cache/yarn";
+    const homedirMock = jest.spyOn(os, "homedir");
+    homedirMock.mockImplementation(() => {
+        return "";
+    });
+
+    expect(() => pathUtils.expandPaths([filePath])).toThrow(
+        "Unable to resolve `~` to HOME"
+    );
+});
diff --git a/__tests__/restore.test.ts b/__tests__/restore.test.ts
index 9323a87..23f03cc 100644
--- a/__tests__/restore.test.ts
+++ b/__tests__/restore.test.ts
@@ -7,15 +7,17 @@ import run from "../src/restore";
 import * as tar from "../src/tar";
 import * as actionUtils from "../src/utils/actionUtils";
 import * as testUtils from "../src/utils/testUtils";
+// import * as pathUtils from "../src/utils/pathUtils";
 
 jest.mock("../src/cacheHttpClient");
 jest.mock("../src/tar");
 jest.mock("../src/utils/actionUtils");
+// jest.mock("../src/utils/pathUtils");
 
 beforeAll(() => {
-    jest.spyOn(actionUtils, "resolvePath").mockImplementation(filePath => {
-        return path.resolve(filePath);
-    });
+    // jest.spyOn(pathUtils, "expandPaths").mockImplementation(filePaths => {
+    //     return filePaths.map(x => path.resolve(x));
+    // });
 
     jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation(
         (key, cacheResult) => {
diff --git a/__tests__/save.test.ts b/__tests__/save.test.ts
index 729f423..476b1ad 100644
--- a/__tests__/save.test.ts
+++ b/__tests__/save.test.ts
@@ -7,11 +7,13 @@ import run from "../src/save";
 import * as tar from "../src/tar";
 import * as actionUtils from "../src/utils/actionUtils";
 import * as testUtils from "../src/utils/testUtils";
+import * as pathUtils from "../src/utils/pathUtils";
 
 jest.mock("@actions/core");
 jest.mock("../src/cacheHttpClient");
 jest.mock("../src/tar");
 jest.mock("../src/utils/actionUtils");
+jest.mock("../src/utils/pathUtils");
 
 beforeAll(() => {
     jest.spyOn(core, "getInput").mockImplementation((name, options) => {
@@ -40,8 +42,8 @@ beforeAll(() => {
         return actualUtils.getSupportedEvents();
     });
 
-    jest.spyOn(actionUtils, "resolvePath").mockImplementation(filePath => {
-        return path.resolve(filePath);
+    jest.spyOn(pathUtils, "expandPaths").mockImplementation(filePaths => {
+        return filePaths.map(x => path.resolve(x));
     });
 
     jest.spyOn(actionUtils, "createTempDirectory").mockImplementation(() => {
diff --git a/__tests__/tar.test.ts b/__tests__/tar.test.ts
index 1284cc4..570f66e 100644
--- a/__tests__/tar.test.ts
+++ b/__tests__/tar.test.ts
@@ -14,7 +14,7 @@ beforeAll(() => {
 });
 
 afterAll(() => {
-    process.env["GITHUB_WORKSPACE"] = undefined;
+    delete process.env["GITHUB_WORKSPACE"];
 });
 
 test("extract tar", async () => {
diff --git a/dist/restore/index.js b/dist/restore/index.js
index 199109e..08316c7 100644
--- a/dist/restore/index.js
+++ b/dist/restore/index.js
@@ -1649,7 +1649,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const io = __importStar(__webpack_require__(1));
 const fs = __importStar(__webpack_require__(747));
-const os = __importStar(__webpack_require__(87));
 const path = __importStar(__webpack_require__(622));
 const uuidV4 = __importStar(__webpack_require__(826));
 const constants_1 = __webpack_require__(694);
@@ -1720,17 +1719,6 @@ function logWarning(message) {
     core.info(`${warningPrefix}${message}`);
 }
 exports.logWarning = logWarning;
-function resolvePath(filePath) {
-    if (filePath[0] === "~") {
-        const home = os.homedir();
-        if (!home) {
-            throw new Error("Unable to resolve `~` to HOME");
-        }
-        return path.join(home, filePath.slice(1));
-    }
-    return path.resolve(filePath);
-}
-exports.resolvePath = resolvePath;
 function getSupportedEvents() {
     return [constants_1.Events.Push, constants_1.Events.PullRequest];
 }
@@ -2704,7 +2692,6 @@ var Inputs;
 (function (Inputs) {
     Inputs["Key"] = "key";
     Inputs["Path"] = "path";
-    Inputs["Paths"] = "paths";
     Inputs["RestoreKeys"] = "restore-keys";
 })(Inputs = exports.Inputs || (exports.Inputs = {}));
 var Outputs;
@@ -2803,10 +2790,6 @@ function run() {
                     .join(", ")} events are supported at this time.`);
                 return;
             }
-            // const cachePath = utils.resolvePath(
-            //     core.getInput(Inputs.Path, { required: true })
-            // );
-            // core.debug(`Cache Path: ${cachePath}`);
             const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true });
             core.saveState(constants_1.State.CacheKey, primaryKey);
             const restoreKeys = core
@@ -2964,7 +2947,7 @@ function execTar(args) {
 }
 function getWorkingDirectory() {
     var _a;
-    return _a = process.env.GITHUB_WORKSPACE, (_a !== null && _a !== void 0 ? _a : process.cwd());
+    return _a = process.env["GITHUB_WORKSPACE"], (_a !== null && _a !== void 0 ? _a : process.cwd());
 }
 function extractTar(archivePath) {
     return __awaiter(this, void 0, void 0, function* () {
@@ -2978,6 +2961,7 @@ function extractTar(archivePath) {
 exports.extractTar = extractTar;
 function createTar(archivePath, sourceDirectories) {
     return __awaiter(this, void 0, void 0, function* () {
+        // TODO: will want to stream sourceDirectories into tar
         const workingDirectory = getWorkingDirectory();
         const args = [
             "-cz",
diff --git a/dist/save/index.js b/dist/save/index.js
index aa8104f..1c83810 100644
--- a/dist/save/index.js
+++ b/dist/save/index.js
@@ -1649,7 +1649,6 @@ Object.defineProperty(exports, "__esModule", { value: true });
 const core = __importStar(__webpack_require__(470));
 const io = __importStar(__webpack_require__(1));
 const fs = __importStar(__webpack_require__(747));
-const os = __importStar(__webpack_require__(87));
 const path = __importStar(__webpack_require__(622));
 const uuidV4 = __importStar(__webpack_require__(826));
 const constants_1 = __webpack_require__(694);
@@ -1720,17 +1719,6 @@ function logWarning(message) {
     core.info(`${warningPrefix}${message}`);
 }
 exports.logWarning = logWarning;
-function resolvePath(filePath) {
-    if (filePath[0] === "~") {
-        const home = os.homedir();
-        if (!home) {
-            throw new Error("Unable to resolve `~` to HOME");
-        }
-        return path.join(home, filePath.slice(1));
-    }
-    return path.resolve(filePath);
-}
-exports.resolvePath = resolvePath;
 function getSupportedEvents() {
     return [constants_1.Events.Push, constants_1.Events.PullRequest];
 }
@@ -2722,6 +2710,7 @@ const cacheHttpClient = __importStar(__webpack_require__(154));
 const constants_1 = __webpack_require__(694);
 const tar_1 = __webpack_require__(943);
 const utils = __importStar(__webpack_require__(443));
+const pathUtils = __importStar(__webpack_require__(914));
 function run() {
     return __awaiter(this, void 0, void 0, function* () {
         try {
@@ -2749,11 +2738,10 @@ function run() {
                 return;
             }
             core.debug(`Cache ID: ${cacheId}`);
-            const cachePaths = core
-                .getInput(constants_1.Inputs.Path, { required: false })
+            const cachePaths = pathUtils.expandPaths(core
+                .getInput(constants_1.Inputs.Path)
                 .split("\n")
-                .filter(x => x !== "")
-                .map(x => utils.resolvePath(x));
+                .filter(x => x !== ""));
             core.debug("Cache Paths:");
             core.debug(`${JSON.stringify(cachePaths)}`);
             const archivePath = path.join(yield utils.createTempDirectory(), "cache.tgz");
@@ -2790,7 +2778,6 @@ var Inputs;
 (function (Inputs) {
     Inputs["Key"] = "key";
     Inputs["Path"] = "path";
-    Inputs["Paths"] = "paths";
     Inputs["RestoreKeys"] = "restore-keys";
 })(Inputs = exports.Inputs || (exports.Inputs = {}));
 var Outputs;
@@ -2891,6 +2878,67 @@ module.exports = v4;
 
 module.exports = require("url");
 
+/***/ }),
+
+/***/ 914:
+/***/ (function(__unusedmodule, exports, __webpack_require__) {
+
+"use strict";
+
+var __importStar = (this && this.__importStar) || function (mod) {
+    if (mod && mod.__esModule) return mod;
+    var result = {};
+    if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];
+    result["default"] = mod;
+    return result;
+};
+Object.defineProperty(exports, "__esModule", { value: true });
+const os = __importStar(__webpack_require__(87));
+const path = __importStar(__webpack_require__(622));
+const globCharacters = ["*", "?", "[", "]"];
+function resolvePath(filePath) {
+    if (filePath[0] === "~") {
+        const home = os.homedir();
+        if (!home) {
+            throw new Error("Unable to resolve `~` to HOME");
+        }
+        return path.join(home, filePath.slice(1));
+    }
+    return path.resolve(filePath);
+}
+exports.resolvePath = resolvePath;
+function isMinimatchPattern(pattern) {
+    if (globCharacters.some(x => pattern.includes(x))) {
+        return true;
+    }
+    return false;
+}
+exports.isMinimatchPattern = isMinimatchPattern;
+function matchDirectories(pattern, workspace) {
+    const directories = path;
+}
+exports.matchDirectories = matchDirectories;
+function expandPaths(filePaths) {
+    const paths = [];
+    const workspace = process.env["GITHUB_WORKSPACE"];
+    for (const filePath of filePaths) {
+        if (isMinimatchPattern(filePath)) {
+            paths.push(filePath);
+        }
+        else if (filePath[0] === "~") {
+            const home = os.homedir();
+            if (!home) {
+                throw new Error("Unable to resolve `~` to HOME");
+            }
+            paths.push(path.join(home, filePath.slice(1)));
+        }
+        paths.push(path.resolve(filePath));
+    }
+    return paths;
+}
+exports.expandPaths = expandPaths;
+
+
 /***/ }),
 
 /***/ 943:
@@ -2948,7 +2996,7 @@ function execTar(args) {
 }
 function getWorkingDirectory() {
     var _a;
-    return _a = process.env.GITHUB_WORKSPACE, (_a !== null && _a !== void 0 ? _a : process.cwd());
+    return _a = process.env["GITHUB_WORKSPACE"], (_a !== null && _a !== void 0 ? _a : process.cwd());
 }
 function extractTar(archivePath) {
     return __awaiter(this, void 0, void 0, function* () {
@@ -2962,6 +3010,7 @@ function extractTar(archivePath) {
 exports.extractTar = extractTar;
 function createTar(archivePath, sourceDirectories) {
     return __awaiter(this, void 0, void 0, function* () {
+        // TODO: will want to stream sourceDirectories into tar
         const workingDirectory = getWorkingDirectory();
         const args = [
             "-cz",
diff --git a/package-lock.json b/package-lock.json
index c15b316..002f504 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -537,6 +537,12 @@
       "integrity": "sha512-Il2DtDVRGDcqjDtE+rF8iqg1CArehSK84HZJCT7AMITlyXRBpuPhqGLDQMowraqqu1coEaimg4ZOqggt6L6L+A==",
       "dev": true
     },
+    "@types/minimatch": {
+      "version": "3.0.3",
+      "resolved": "https://registry.npmjs.org/@types/minimatch/-/minimatch-3.0.3.tgz",
+      "integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
+      "dev": true
+    },
     "@types/nock": {
       "version": "11.1.0",
       "resolved": "https://registry.npmjs.org/@types/nock/-/nock-11.1.0.tgz",
@@ -900,8 +906,7 @@
     "balanced-match": {
       "version": "1.0.0",
       "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
-      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
-      "dev": true
+      "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c="
     },
     "base": {
       "version": "0.11.2",
@@ -977,7 +982,6 @@
       "version": "1.1.11",
       "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
       "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
-      "dev": true,
       "requires": {
         "balanced-match": "^1.0.0",
         "concat-map": "0.0.1"
@@ -1294,8 +1298,7 @@
     "concat-map": {
       "version": "0.0.1",
       "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
-      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
-      "dev": true
+      "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s="
     },
     "contains-path": {
       "version": "0.1.0",
@@ -4238,7 +4241,6 @@
       "version": "3.0.4",
       "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
       "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
-      "dev": true,
       "requires": {
         "brace-expansion": "^1.1.7"
       }
diff --git a/package.json b/package.json
index 66952be..2401f05 100644
--- a/package.json
+++ b/package.json
@@ -27,10 +27,12 @@
     "@actions/exec": "^1.0.1",
     "@actions/http-client": "^1.0.6",
     "@actions/io": "^1.0.1",
+    "minimatch": "^3.0.4",
     "uuid": "^3.3.3"
   },
   "devDependencies": {
     "@types/jest": "^24.0.13",
+    "@types/minimatch": "^3.0.3",
     "@types/nock": "^11.1.0",
     "@types/node": "^12.0.4",
     "@types/uuid": "^3.4.5",
diff --git a/src/restore.ts b/src/restore.ts
index 20e8151..f70c17b 100644
--- a/src/restore.ts
+++ b/src/restore.ts
@@ -19,11 +19,6 @@ async function run(): Promise<void> {
             return;
         }
 
-        // const cachePath = utils.resolvePath(
-        //     core.getInput(Inputs.Path, { required: true })
-        // );
-        // core.debug(`Cache Path: ${cachePath}`);
-
         const primaryKey = core.getInput(Inputs.Key, { required: true });
         core.saveState(State.CacheKey, primaryKey);
 
diff --git a/src/save.ts b/src/save.ts
index 7c32a8e..4facb1e 100644
--- a/src/save.ts
+++ b/src/save.ts
@@ -4,6 +4,7 @@ import * as cacheHttpClient from "./cacheHttpClient";
 import { Events, Inputs, State } from "./constants";
 import { createTar } from "./tar";
 import * as utils from "./utils/actionUtils";
+import * as pathUtils from "./utils/pathUtils";
 
 async function run(): Promise<void> {
     try {
@@ -43,11 +44,12 @@ async function run(): Promise<void> {
             return;
         }
         core.debug(`Cache ID: ${cacheId}`);
-        const cachePaths = core
-            .getInput(Inputs.Path)
-            .split("\n")
-            .filter(x => x !== "")
-            .map(x => utils.resolvePath(x));
+        const cachePaths = pathUtils.expandPaths(
+            core
+                .getInput(Inputs.Path)
+                .split("\n")
+                .filter(x => x !== "")
+        );
 
         core.debug("Cache Paths:");
         core.debug(`${JSON.stringify(cachePaths)}`);
diff --git a/src/tar.ts b/src/tar.ts
index c55e06e..0d91bfc 100644
--- a/src/tar.ts
+++ b/src/tar.ts
@@ -44,6 +44,7 @@ export async function createTar(
     archivePath: string,
     sourceDirectories: string[]
 ): Promise<void> {
+    // TODO: will want to stream sourceDirectories into tar
     const workingDirectory = getWorkingDirectory();
     const args = [
         "-cz",
diff --git a/src/utils/actionUtils.ts b/src/utils/actionUtils.ts
index f6369fb..a3960c7 100644
--- a/src/utils/actionUtils.ts
+++ b/src/utils/actionUtils.ts
@@ -1,7 +1,6 @@
 import * as core from "@actions/core";
 import * as io from "@actions/io";
 import * as fs from "fs";
-import * as os from "os";
 import * as path from "path";
 import * as uuidV4 from "uuid/v4";
 
@@ -82,18 +81,6 @@ export function logWarning(message: string): void {
     core.info(`${warningPrefix}${message}`);
 }
 
-export function resolvePath(filePath: string): string {
-    if (filePath[0] === "~") {
-        const home = os.homedir();
-        if (!home) {
-            throw new Error("Unable to resolve `~` to HOME");
-        }
-        return path.join(home, filePath.slice(1));
-    }
-
-    return path.resolve(filePath);
-}
-
 export function getSupportedEvents(): string[] {
     return [Events.Push, Events.PullRequest];
 }
diff --git a/src/utils/pathUtils.ts b/src/utils/pathUtils.ts
new file mode 100644
index 0000000..43c2b76
--- /dev/null
+++ b/src/utils/pathUtils.ts
@@ -0,0 +1,63 @@
+import * as os from "os";
+import * as path from "path";
+import { readdirSync } from "fs";
+import { IOptions, Minimatch } from "minimatch";
+
+const globCharacters: string[] = ["*", "?", "[", "]"];
+const options: IOptions = {
+    nocase: true,
+    dot: true,
+    nobrace: true
+};
+
+// export function resolvePath(filePath: string): string {
+//     if (filePath[0] === "~") {
+//         const home = os.homedir();
+//         if (!home) {
+//             throw new Error("Unable to resolve `~` to HOME");
+//         }
+//         return path.join(home, filePath.slice(1));
+//     }
+
+//     return path.resolve(filePath);
+// }
+
+export function isMinimatchPattern(pattern: string): boolean {
+    if (globCharacters.some(x => pattern.includes(x))) {
+        return true;
+    }
+
+    return false;
+}
+
+export function matchDirectories(pattern: string, workspace: string): string[] {
+    const directories = readdirSync(workspace, { withFileTypes: true })
+        .filter(dirent => dirent.isDirectory())
+        .map(dirent => dirent.name);
+
+    const minimatch = new Minimatch(pattern, options);
+    const matches = directories.filter(x => minimatch.match(x));
+
+    return matches;
+}
+
+export function expandPaths(filePaths: string[]): string[] {
+    const paths: string[] = [];
+    const workspace = process.env["GITHUB_WORKSPACE"] ?? process.cwd();
+
+    for (const filePath of filePaths) {
+        if (isMinimatchPattern(filePath)) {
+            paths.push(...matchDirectories(filePath, workspace));
+        } else if (filePath[0] === "~") {
+            const home = os.homedir();
+            if (!home) {
+                throw new Error("Unable to resolve `~` to HOME");
+            }
+            paths.push(path.join(home, filePath.slice(1)));
+        } else {
+            paths.push(path.resolve(filePath));
+        }
+    }
+
+    return paths;
+}