-
Notifications
You must be signed in to change notification settings - Fork 3
OAuth support with external idP #25
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
base: main
Are you sure you want to change the base?
Conversation
src/mcp_server_uyuni/server.py
Outdated
AUTH_SERVER = os.environ.get("UYUNI_AUTH_SERVER") | ||
|
||
auth_provider = AuthProvider(AUTH_SERVER) if AUTH_SERVER else None | ||
mcp = FastMCP("mcp-server-uyuni", auth=auth_provider) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
using an auth makes the transport protocol be http?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think auth parameter does nothing if the transport is set to stdio.
In the final code we should validate these kind of things in the config values and write warnings in the logs when there's conflicting stuff like if there's an IDP specified and also stdio is selected at the same time, etc.
Another example is that it should be either Uyuni user/pass values or external idP.
I'm not planning to mark this PR ready to merge any time soon, so it's only skeleton code.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see it depends on having the UYUNI_MCP_TRANSPORT set to Transport.HTTP.value
mcp-server-uyuni/src/mcp_server_uyuni/server.py
Line 1254 in 8e55817
mcp.run(transport="streamable-http") |
I think it would be safer if we remove that environment variable and instead we make the transport be HTTP if and only if there is an AUTH_SERVER. This way, you only use HTTP if you have authentication.
This way, we do not have an MCP server running with HTTP without auth that anyone can use to access the uyuni server.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As long as we make it clear with docs, log entries and comments on the example config, I think we can let it in case people wanna test/develop the server with simple user/pass credentials.
src/mcp_server_uyuni/auth.py
Outdated
super().__init__( | ||
token_verifier=verifier, | ||
authorization_servers=[AnyHttpUrl(auth_server)], | ||
resource_server_url="http://localhost:8000/mcp", #TODO: Get URL dynamically? |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
you can use host and port properties of the FastMCP Server implementation
https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L162
https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L163
you will have to pass them to the class constructor, or pass the FastMCP object itself.
In case we need to setup different known urls, because of different clients expect differently, we could use a custom route: https://github.com/jlowin/fastmcp/blob/main/src/fastmcp/server/server.py#L429 . We might not need that if clients are fixed upstream. |
6ec898f
to
be7a8b5
Compare
Allows using an external idP for OAuth 2 authentication with protected resource metadata.
Fixes: https://github.com/SUSE/spacewalk/issues/27633
How to test with Keycloak (insecure!)
Setting up the client
uyuni
)mcp-server-uyuni
)http://localhost:7777/oauth/callback
audience-mapper
) and selectmcp-server-uyuni
in the Included Client Audience tab.Save
.uyuni-mcp-server
client details, to "Client scopes" tab and addmcp:read
(Default) andmcp:write
(Optional) client scopes.Setting up a test user
username
andemail
Test config for gemini-cli
Gemini doesn't seem to be able to consume protected resource metadata files properly, so we need to add the auth endpoints manually.
.gemini/settings.json
:Testing with MCP inspector
http://localhost:8000
mcp-server-uyuni
(or whatever is set in Keycloak)Testing with VS Code
Add the following to the
mcp.json
file:Click "Connect" and follow the instructions for the OAuth flow. When instructed, add the VSCode callback URLs to the Keycloak client "Valid Callback URLs".