Skip to content
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

Feature Request: support OAuth2 #879

Open
andreasbrett opened this issue Nov 15, 2024 · 4 comments
Open

Feature Request: support OAuth2 #879

andreasbrett opened this issue Nov 15, 2024 · 4 comments

Comments

@andreasbrett
Copy link

andreasbrett commented Nov 15, 2024

Problem/Motivation

Using OAuth2 to access the Tailscale API would introduce several improvements. First and foremost OAuth2 clients are not temporary, so users will not have to re-create API keys every 90 days.

More importantly though with OAuth2 tailnet owners can scope the API access that is granted to the module and not provide owner permissions. In its current state the module only reads device info, so providing a fully-permitted access token that can be used to manage the whole tailnet is far too broad. Creating an OAuth2 client in Tailscale that is scoped to only devices:core:read would provide least privileged permissions (and would let me sleep better...).

https://tailscale.com/kb/1215/oauth-clients

Expected behavior

(What you expected to happen)

Actual behavior

(What actually happened)

Steps to reproduce

(How can someone else make/see it happen)

Proposed changes

I'm not a developer and can't provide a PR to add OAuth2 but I took the liberty of trying out the OAuth2 module for Python and it worked right away with my butchered approach in tailscale.py:

[...]
from oauthlib.oauth2 import BackendApplicationClient
from requests_oauthlib import OAuth2Session
[...]
class Tailscale:
    """Main class for handling connections with the Tailscale API."""

    tailnet: str
    api_key: str
    oauth2_client_id: str
    oauth2_client_secret: str
[...]
    def __init__(self, tailnet, api_key=None, oauth2_client_id=None, oauth2_client_secret=None):
        self.tailnet = tailnet
        self.api_key = api_key
        self.oauth2_client_id = oauth2_client_id
        self.oauth2_client_secret = oauth2_client_secret

    async def _fetch_token(self):
        client = BackendApplicationClient(client_id=self.oauth2_client_id)
        oauth = OAuth2Session(client=client)
        token = oauth.fetch_token(token_url="https://api.tailscale.com/api/v2/oauth/token", client_id=self.oauth2_client_id, client_secret=self.oauth2_client_secret)
        return token["access_token"]

    async def _request(
        self,
        uri: str,
        *,
        method: str = METH_GET,
        data: dict[str, Any] | None = None,
    ) -> str:

        if self.api_key is None and self.oauth2_client_id is not None and self.oauth2_client_secret is not None:
            self.api_key = await self._fetch_token()

[...]

This of course misses all the bells, whistles, error handling and refreshing tokens. I just didn't want to come empty-handed...

Copy link

There hasn't been any activity on this issue recently, so we clean up some of the older and inactive issues.
Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by leaving a comment 👍
This issue has now been marked as stale and will be closed if no further activity occurs. Thanks!

@github-actions github-actions bot added the stale There has not been activity on this issue or PR for quite some time. label Dec 16, 2024
@andreasbrett
Copy link
Author

Still a huge improvement IMHO.

@github-actions github-actions bot removed the stale There has not been activity on this issue or PR for quite some time. label Dec 17, 2024
Copy link

There hasn't been any activity on this issue recently, so we clean up some of the older and inactive issues.
Please make sure to update to the latest version and check if that solves the issue. Let us know if that works for you by leaving a comment 👍
This issue has now been marked as stale and will be closed if no further activity occurs. Thanks!

@github-actions github-actions bot added the stale There has not been activity on this issue or PR for quite some time. label Jan 17, 2025
@andreasbrett
Copy link
Author

Potential for improving both usability and security is still the same.

@github-actions github-actions bot removed the stale There has not been activity on this issue or PR for quite some time. label Jan 18, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant