Excellent question. This is a common security and organizational challenge when working with third-party tools and automations.
The short answer is no, it is not possible to directly authorize a GitHub App or OAuth App to access only specific directories within a repository.
GitHub's permission model operates at the repository level. When you grant an app access to a repository, you grant it permissions (like Read
on code, or Read & write
on issues) for the entire repository. There is no native feature to scope that access down to a file or directory path.
However, there are several effective workarounds and architectural patterns to achieve a similar result. The best choice depends on your specific use case (e.g., CI/CD, code analysis, a custom bot).
Here are the most common strategies, from simplest to most complex:
This is the cleanest and most secure solution if your architecture allows for it.
- How it works: Move the directory you want the app to access into its own dedicated repository. Then, grant the app access only to that new, smaller repository.
- Pros:
- Most Secure: The app genuinely has zero access to your other code. This follows the principle of least privilege perfectly.
- Clear Separation: Enforces a clear boundary between different parts of your project.
- Cons:
- Major Refactoring: Can be a significant architectural change, potentially breaking build processes, Git history, and developer workflows.
- Not Always Feasible: Impractical for tightly coupled codebases (e.g., a frontend app in
/frontend
and its backend in/backend
within a monorepo).
This is the most common solution for automation and deployment workflows. You limit when the action runs, not what it can access.
- How it works: You grant the GitHub Actions workflow permission to the entire repository, but you configure the workflow to only trigger when changes are made within specific directories.
- Example
workflow.yml
:name: Deploy Website on: push: branches: - main paths: - 'apps/my-website/**' # Only run this workflow for changes in this directory - '.github/workflows/deploy-website.yml' # Also run if the workflow file itself changes jobs: deploy: runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 - name: Build and Deploy Website # Your deployment script only works with files from 'apps/my-website' run: | cd apps/my-website npm install npm run build # ... deploy commands ...
- Pros:
- Easy to Implement: No need to restructure your repository.
- Effective for CI/CD: Perfect for triggering deployments or tests for a specific part of a monorepo.
- Cons:
- Security Caveat: The workflow's token (
secrets.GITHUB_TOKEN
) still has access to the entire repository. If a malicious dependency in your build script steals the token, it can access the whole repo, not just the specified directory. The limitation is on the trigger, not the access.
- Security Caveat: The workflow's token (
This pattern provides the ultimate control but requires significant development effort.
- How it works: You create your own small application (e.g., a serverless function) that acts as a secure intermediary.
- Your custom service is granted full access to the GitHub repository.
- The third-party app is given credentials to talk to your service, not directly to GitHub.
- When the third-party app needs to read a file, it makes a request to your service (e.g.,
GET /api/files/my-directory/file.js
). - Your service validates that the requested path is within the allowed directory and then uses its powerful GitHub token to fetch the file from the repo and return it to the app.
- Pros:
- Granular Control: You can implement any logic you want (e.g., allow reads but not writes, only allow access to
.js
files, etc.). - Maximum Security for the Third-Party App: The app never gets a token that can access your GitHub repo directly.
- Granular Control: You can implement any logic you want (e.g., allow reads but not writes, only allow access to
- Cons:
- High Complexity: You have to build, host, and maintain this middle-man service.
- Shifts Responsibility: You are now responsible for the security of your broker service and its powerful GitHub token.
If your goal is to give a server (like a production VM) git clone
access for deployment, a Deploy Key is a good option.
- How it works: A Deploy Key is an SSH key that you add to a single repository's settings. It grants read-only (or optionally, read-write) access to that one repo.
- Pros:
- Simple for
git
operations: Excellent for pulling code onto a server. - Scoped to one repository.
- Simple for
- Cons:
- Still repository-scoped: It does not limit access to a directory.
- Not for API access: It's for
git
protocol access (clone/pull/push), not for interacting with the GitHub API (e.g., managing issues or pull requests).
Method | How it Works | Best For | Security |
---|---|---|---|
Split Repository | Move directory to a new repo and grant access to it. | When security is paramount and architecture allows. | Very High |
GitHub Actions paths |
Trigger workflows only on changes to a specific path. | CI/CD, tests, and deployments in a monorepo. | Medium (Token has full access) |
Custom Broker Service | Build a middle-man app to proxy and validate requests. | Highly sensitive environments needing custom logic. | High (If built correctly) |
Deploy Keys | An SSH key granting git clone access to one repo. |
Giving a deployment server pull/push access. | High (For its specific purpose) |
- For CI/CD in a monorepo, use GitHub Actions with
paths
filters. It's the standard, industry-accepted practice. - For maximum security with a third-party app, the best but hardest path is to split the repository.
- If you can't split the repo and the security risk of the Actions token is unacceptable, you must consider building a custom broker service.