-
Notifications
You must be signed in to change notification settings - Fork 135
User based authentication methods #130
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from 25 commits
Commits
Show all changes
32 commits
Select commit
Hold shift + click to select a range
0b14c8e
noot
elee1766 4cec54b
noot
elee1766 2513168
wip
elee1766 0467d2f
wip
elee1766 8babb38
wip
elee1766 3d6fc4d
noot
elee1766 4132d13
noot
elee1766 2679714
noot
elee1766 f179def
Merge branch 'main' into proxy_oauth
elee1766 e3a11d8
merge
elee1766 4d8d02f
noot
elee1766 99c40b2
noot
elee1766 8849309
add some ai documentation
elee1766 00ef65f
multiple transports
elee1766 4920120
argon2 fix
elee1766 6b818a2
npm i
elee1766 f0762d2
merge
elee1766 5d1a32e
change default token expiry
elee1766 c9445c8
fix types? and merge
elee1766 cb18962
noot
elee1766 f12dec6
merge
elee1766 c6a15ad
fix build
elee1766 ba6a75d
remove unused env var
elee1766 a5c9db8
add some logging
elee1766 bcc4863
add GITLAB_API_URL to the examples
elee1766 d8d0b45
fix merge conflicts
elee1766 7f7062a
argon2 warning
elee1766 4ab6eb1
Fix list of tools
hwittenborn 6f7df40
Merge pull request #205 from hwittenborn/main
iwakitakuma33 7e985af
feat: Add NPM publish workflow for automated package publishing (#208)
zereight 71a71b2
merge
elee1766 f6987cc
single logger
elee1766 File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,147 @@ | ||
# GitLab MCP OAuth2 Proxy Configuration | ||
|
||
This guide explains how to configure the GitLab MCP server to use OAuth2 proxy authentication, allowing users to authenticate with GitLab OAuth2 applications instead of using personal access tokens. | ||
|
||
## Overview | ||
|
||
The OAuth2 proxy mode enables dynamic client registration and token management, providing a more secure and flexible authentication method compared to static personal access tokens. | ||
|
||
**Note:** OAuth2 proxy mode is only available when using SSE or STREAMABLE_HTTP transport modes. It is not supported with STDIO transport. | ||
|
||
## Required Environment Variables | ||
|
||
To enable OAuth2 proxy mode, you must set the following environment variables: | ||
|
||
### Core OAuth2 Configuration | ||
|
||
```bash | ||
# GitLab OAuth2 Application Credentials | ||
GITLAB_OAUTH2_CLIENT_ID=your_gitlab_app_id | ||
GITLAB_OAUTH2_CLIENT_SECRET=your_gitlab_app_secret | ||
|
||
# GitLab OAuth2 Endpoints | ||
GITLAB_OAUTH2_AUTHORIZATION_URL=https://gitlab.com/oauth/authorize | ||
GITLAB_OAUTH2_TOKEN_URL=https://gitlab.com/oauth/token | ||
GITLAB_OAUTH2_ISSUER_URL=https://gitlab.com | ||
GITLAB_OAUTH2_BASE_URL=http://localhost:3000 # Your MCP server URL | ||
|
||
# OAuth2 Redirect Configuration | ||
GITLAB_OAUTH2_REDIRECT_URL=http://localhost:3000/callback | ||
``` | ||
|
||
### Optional Configuration | ||
|
||
```bash | ||
# Token Revocation Endpoint (optional) | ||
GITLAB_OAUTH2_REVOCATION_URL=https://gitlab.com/oauth/revoke | ||
|
||
# Database Path (defaults to in-memory if not set) | ||
GITLAB_OAUTH2_DB_PATH=/path/to/oauth.db | ||
``` | ||
|
||
## Setting Up a GitLab OAuth2 Application | ||
|
||
1. Go to your GitLab instance (e.g., https://gitlab.com) | ||
2. Navigate to **User Settings** → **Applications** | ||
3. Create a new application with: | ||
- **Name**: Your MCP Server (or any descriptive name) | ||
- **Redirect URI**: Must match `GITLAB_OAUTH2_REDIRECT_URL` exactly (e.g., `http://localhost:3000/callback`) | ||
- **Scopes**: Select the following: | ||
- `api` - Access the authenticated user's API | ||
- `openid` - Authenticate using OpenID Connect | ||
- `profile` - Read user's profile data | ||
- `email` - Read user's email address | ||
|
||
4. After creation, GitLab will provide: | ||
- **Application ID**: Use this for `GITLAB_OAUTH2_CLIENT_ID` | ||
- **Secret**: Use this for `GITLAB_OAUTH2_CLIENT_SECRET` | ||
|
||
## Configuration Examples | ||
|
||
### Development Setup (localhost) | ||
|
||
```bash | ||
# .env file | ||
GITLAB_API_URL=https://gitlab.com | ||
|
||
GITLAB_OAUTH2_CLIENT_ID=your_app_id_here | ||
GITLAB_OAUTH2_CLIENT_SECRET=your_app_secret_here | ||
GITLAB_OAUTH2_AUTHORIZATION_URL=https://gitlab.com/oauth/authorize | ||
GITLAB_OAUTH2_TOKEN_URL=https://gitlab.com/oauth/token | ||
GITLAB_OAUTH2_ISSUER_URL=https://gitlab.com | ||
GITLAB_OAUTH2_BASE_URL=http://localhost:3000 | ||
GITLAB_OAUTH2_REDIRECT_URL=http://localhost:3000/callback | ||
``` | ||
|
||
### Production Setup | ||
|
||
```bash | ||
# .env file | ||
GITLAB_API_URL=https://gitlab.company.com | ||
elee1766 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
||
GITLAB_OAUTH2_CLIENT_ID=your_app_id_here | ||
GITLAB_OAUTH2_CLIENT_SECRET=your_app_secret_here | ||
GITLAB_OAUTH2_AUTHORIZATION_URL=https://gitlab.company.com/oauth/authorize | ||
GITLAB_OAUTH2_TOKEN_URL=https://gitlab.company.com/oauth/token | ||
GITLAB_OAUTH2_ISSUER_URL=https://gitlab.company.com | ||
GITLAB_OAUTH2_BASE_URL=https://mcp.company.com | ||
GITLAB_OAUTH2_REDIRECT_URL=https://mcp.company.com/callback | ||
GITLAB_OAUTH2_DB_PATH=/var/lib/gitlab-mcp/oauth.db | ||
``` | ||
|
||
## Database Storage | ||
|
||
By default, the OAuth2 proxy uses an in-memory SQLite database. For production use, specify a persistent database path: | ||
|
||
```bash | ||
GITLAB_OAUTH2_DB_PATH=/path/to/persistent/oauth.db | ||
elee1766 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
``` | ||
|
||
The database stores: | ||
- OAuth client registrations | ||
- State mappings for OAuth flow | ||
- Access token hashes (using Argon2 for security) | ||
|
||
## Security Considerations | ||
|
||
1. **Client Secrets**: Never commit `GITLAB_OAUTH2_CLIENT_SECRET` to version control | ||
2. **HTTPS**: Always use HTTPS for production deployments | ||
3. **Token Storage**: Access tokens are hashed using Argon2 before storage | ||
4. **Token Expiry**: Tokens expire after 1 hour by default | ||
5. **State Expiry**: OAuth state parameters expire after 15 minutes | ||
|
||
## Troubleshooting | ||
|
||
### Common Issues | ||
|
||
1. **"Protected resource URL mismatch"** | ||
- Ensure `GITLAB_OAUTH2_BASE_URL` matches your server's actual URL | ||
- Check that the redirect URI in GitLab matches `GITLAB_OAUTH2_REDIRECT_URL` | ||
|
||
2. **"Invalid redirect URI"** | ||
- The redirect URI must match exactly (including protocol and port) | ||
- No trailing slashes unless specified in GitLab | ||
|
||
3. **"Invalid scope"** | ||
- Ensure your GitLab OAuth app has the required scopes enabled | ||
- The MCP server requests: `api`, `openid`, `profile`, `email` | ||
|
||
|
||
## Starting the Server | ||
|
||
OAuth2 proxy mode requires SSE or STREAMABLE_HTTP transport. | ||
|
||
The server will log: | ||
``` | ||
Configuring GitLab OAuth2 proxy authentication | ||
``` | ||
|
||
**Note:** STDIO transport mode does not support OAuth2 proxy authentication. | ||
|
||
## Client Configuration | ||
|
||
MCP clients connecting to an OAuth2-enabled server should use the OAuth2 flow instead of providing a GitLab token directly. The server will handle dynamic client registration and token management automatically. | ||
|
||
## Note | ||
|
||
OAuth2 proxy support is currently in beta. While functional, it may have limitations compared to personal access token authentication. Please report any issues to the project's issue tracker. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,183 @@ | ||
# GitLab MCP Passthrough Authentication Mode | ||
|
||
This guide explains how to configure the GitLab MCP server to use passthrough authentication mode, where users provide their own GitLab Personal Access Token (PAT) with each request. | ||
|
||
## Overview | ||
|
||
Passthrough mode allows multiple users to use the same MCP server instance with their own GitLab credentials. Each user provides their GitLab Personal Access Token via the `Gitlab-Token` header, and the server uses that token for all GitLab API requests. | ||
|
||
This mode is ideal for: | ||
- Multi-user environments | ||
- Scenarios where you don't want to store tokens on the server | ||
- Testing with different access levels | ||
|
||
## Configuration | ||
|
||
To enable passthrough mode, set the following environment variable: | ||
|
||
```bash | ||
GITLAB_PAT_PASSTHROUGH=true | ||
``` | ||
|
||
**Important:** When using passthrough mode, do not set: | ||
- `GITLAB_PERSONAL_ACCESS_TOKEN` | ||
- `GITLAB_OAUTH2_CLIENT_ID` (or any OAuth2 configuration) | ||
|
||
## How It Works | ||
|
||
1. The MCP server starts without any pre-configured authentication | ||
2. Each client request must include a `Gitlab-Token` header with a valid GitLab PAT | ||
3. The server uses the provided token for that specific request | ||
4. No tokens are stored or cached by the server | ||
|
||
## Client Configuration | ||
|
||
### Using with MCP Client | ||
|
||
When connecting to a passthrough-enabled server, clients must provide the GitLab token with each request: | ||
|
||
```typescript | ||
// Example client configuration | ||
const client = new MCPClient({ | ||
url: 'http://localhost:3000', | ||
headers: { | ||
'Gitlab-Token': 'your-gitlab-personal-access-token' | ||
} | ||
}); | ||
``` | ||
|
||
### Using with cURL | ||
|
||
```bash | ||
curl -H "Gitlab-Token: your-gitlab-personal-access-token" \ | ||
http://localhost:3000/your-endpoint | ||
``` | ||
|
||
### Using with HTTP Libraries | ||
|
||
```javascript | ||
// Node.js with fetch | ||
const response = await fetch('http://localhost:3000/your-endpoint', { | ||
headers: { | ||
'Gitlab-Token': 'your-gitlab-personal-access-token' | ||
} | ||
}); | ||
``` | ||
|
||
## Creating a GitLab Personal Access Token | ||
|
||
1. Go to GitLab (e.g., https://gitlab.com) | ||
2. Navigate to **User Settings** → **Access Tokens** | ||
3. Create a new token with: | ||
- **Token name**: Descriptive name (e.g., "MCP Client") | ||
- **Expiration date**: Set as needed | ||
- **Scopes**: Select based on your needs: | ||
- `api` - Full API access (recommended) | ||
- `read_api` - Read-only API access | ||
- `read_repository` - Read repository content | ||
- `write_repository` - Write repository content | ||
|
||
4. Copy the generated token and use it in the `Gitlab-Token` header | ||
|
||
## Security Considerations | ||
|
||
1. **Token Transmission**: Tokens are sent with every request | ||
- Always use HTTPS in production to encrypt tokens in transit | ||
- Never log or store tokens on the client side in plain text | ||
|
||
2. **No Server Storage**: The server does not store any tokens | ||
- Each request is authenticated independently | ||
- No session management or token caching | ||
|
||
3. **Token Scope**: Users control their own access levels | ||
- Each user's token determines what they can access | ||
- Server has no control over permissions | ||
|
||
## Error Handling | ||
|
||
### Missing Token | ||
If a request is made without the `Gitlab-Token` header: | ||
``` | ||
Status: 401 Unauthorized | ||
Body: "Please set a Gitlab-Token header in your request" | ||
``` | ||
|
||
### Invalid Token Format | ||
If the token is not a string or is sent multiple times: | ||
``` | ||
Status: 401 Unauthorized | ||
Body: "Gitlab-Token must only be set once" | ||
``` | ||
|
||
### Invalid GitLab Token | ||
If GitLab rejects the token: | ||
``` | ||
Status: 401 Unauthorized | ||
Body: GitLab API error message | ||
``` | ||
|
||
## Starting the Server | ||
|
||
Start the server with passthrough mode enabled: | ||
|
||
```bash | ||
GITLAB_PAT_PASSTHROUGH=true npm dev | ||
``` | ||
|
||
The server will log: | ||
``` | ||
Configuring GitLab PAT passthrough authentication. Users must set the Gitlab-Token header in their requests | ||
``` | ||
|
||
## Comparison with Other Modes | ||
|
||
| Feature | Passthrough | Static PAT | OAuth2 Proxy | | ||
|---------|------------|------------|--------------| | ||
| Multi-user support | ✅ Yes | ❌ No | ✅ Yes | | ||
| Token storage | ❌ None | ✅ Server | ✅ Database | | ||
| Setup complexity | Low | Low | High | | ||
| Transport support | All | All | SSE/HTTP only | | ||
| User token control | ✅ Full | ❌ None | ⚠️ Limited | | ||
|
||
## Example: Full Request Flow | ||
|
||
1. User creates a GitLab PAT with necessary scopes | ||
2. User configures their MCP client with the token: | ||
```javascript | ||
const client = new MCPClient({ | ||
url: 'http://localhost:3000', | ||
headers: { | ||
'Gitlab-Token': 'glpat-xxxxxxxxxxxxxxxxxxxx' | ||
} | ||
}); | ||
``` | ||
3. Client makes a request to list projects | ||
4. MCP server receives request with token header | ||
5. Server forwards the token to GitLab API | ||
6. GitLab validates token and returns data | ||
7. Server returns data to client | ||
|
||
## Troubleshooting | ||
|
||
### Token Not Working | ||
- Verify the token has not expired | ||
- Check that the token has the required scopes | ||
- Ensure the token is from the correct GitLab instance | ||
- Try the token directly with GitLab API to verify it works | ||
|
||
### Multiple Users Issues | ||
- Each user must use their own token | ||
- Tokens should not be shared between users | ||
- Consider OAuth2 mode for better multi-user management | ||
|
||
## Best Practices | ||
|
||
1. **Token Rotation**: Regularly rotate PATs for security | ||
2. **Minimal Scopes**: Use tokens with only necessary scopes | ||
3. **HTTPS Only**: Always use HTTPS in production | ||
4. **Client Security**: Store tokens securely on client side | ||
5. **Monitoring**: Log request counts but never log tokens | ||
|
||
## Note | ||
|
||
Passthrough mode is ideal for development and multi-user scenarios where each user manages their own credentials. For production deployments with many users, consider using OAuth2 proxy mode for better token management and security. |
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.