magic-api-proxy


Namemagic-api-proxy JSON
Version 0.1.14 PyPI version JSON
download
home_pagehttps://github.com/rienafairefr/magic-api-proxy
SummaryA stateless API proxy
upload_time2023-03-22 21:48:11
maintainer
docs_urlNone
authoradapted from Alethea Katherine Flowers
requires_python>=3.6
license
keywords api github proxy
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage
            # Magic API Proxy

This is a *stateless* API proxy that allows creation and use of *access-limited* API tokens.

Basically, it's identity and access management for API tokens.


## Why is this useful?

GitHub's API tokens (or other APIs, like DigitalOcean's) do not allow fine-grained control over which actions a token can perform (see this [Dear GitHub issue](https://github.com/dear-github/dear-github/issues/113)). For example, you basically have to create a token that has full control over a repository to allow a token to just apply labels to issues.

This can be problematic. When you have many jobs, processes, and/or bots interacting with the GitHub API you increase the likelihood that a token could be compromised and tokens with broad permissions have very high consequences. 

This proxy allows you to create API tokens with fine-grained permissions (a *magic token*) and then talk to an API using those magic tokens through a proxy. The proxy validates the magic token is allows to perform the requested action and then forwards the request to the API using the real API token.


## What does *stateless* mean?

This proxy requires no backing storage and stores all of its state in the magic token itself. Although the plugin system permits to add a stateful layer if you so wish. e.g. allowing a token to create a record on a DNS provider, and delete it afterwards, but not delete any other record. *TODO*: document plugin system


## What? How?

The proxy uses asymmetric cryptography (a public and private key pair) and [JWTs](https://jwt.io) to encode its state into the magic token.

Each magic token is a simple JWT signed by the proxy's *private key* with these claims:

```
{
  "iat": 1541616032,
  "exp": 1699296032,
  "token": "[long encrypted key]",
  "allowed": [
    "GET /user",
    "GET /repos/theacodes/nox/issues"
  ]
}
```

The `token` claim is an encrypted version of the raw API token. It's encrypted using the proxy's **public key**, so that only the proxy itself can decrypt it (using its **private** key).

The allowed claim determines what the magic token has access to. This proxy has a basic, rudimentary scope implementation described below

The JWT is generated and signed by the proxy itself using its **private key**. This means the contents can not be tampered with without invalidating the JWT.


## Scoping

By default, this proxy has a simple scope strategy using the format:

```
METHOD /url/pattern
```

Where `METHOD` can be `GET`, `POST`, `PUT`, etc. and `/url/pattern` can be any regular expression that's used to check the URL.

For instance, to create a token that has access to any repository's issues in `someorg`, you could do:

```
GET /repos/someorg/.+?/issues
```


## Usage

TODO


## Disclaimer

This is was adaptaed from an unofficial inside-Google project, experimental. This is not a magic bullet for security. You assume all risks when using this project.

            

Raw data

            {
    "_id": null,
    "home_page": "https://github.com/rienafairefr/magic-api-proxy",
    "name": "magic-api-proxy",
    "maintainer": "",
    "docs_url": null,
    "requires_python": ">=3.6",
    "maintainer_email": "",
    "keywords": "api github proxy",
    "author": "adapted from Alethea Katherine Flowers",
    "author_email": "matthieu@mmea.fr",
    "download_url": "https://files.pythonhosted.org/packages/de/99/a9ceca12836b8ca24667a2132c85beca704191dcfaf4de5103c35f94188f/magic-api-proxy-0.1.14.tar.gz",
    "platform": null,
    "description": "# Magic API Proxy\n\nThis is a *stateless* API proxy that allows creation and use of *access-limited* API tokens.\n\nBasically, it's identity and access management for API tokens.\n\n\n## Why is this useful?\n\nGitHub's API tokens (or other APIs, like DigitalOcean's) do not allow fine-grained control over which actions a token can perform (see this [Dear GitHub issue](https://github.com/dear-github/dear-github/issues/113)). For example, you basically have to create a token that has full control over a repository to allow a token to just apply labels to issues.\n\nThis can be problematic. When you have many jobs, processes, and/or bots interacting with the GitHub API you increase the likelihood that a token could be compromised and tokens with broad permissions have very high consequences. \n\nThis proxy allows you to create API tokens with fine-grained permissions (a *magic token*) and then talk to an API using those magic tokens through a proxy. The proxy validates the magic token is allows to perform the requested action and then forwards the request to the API using the real API token.\n\n\n## What does *stateless* mean?\n\nThis proxy requires no backing storage and stores all of its state in the magic token itself. Although the plugin system permits to add a stateful layer if you so wish. e.g. allowing a token to create a record on a DNS provider, and delete it afterwards, but not delete any other record. *TODO*: document plugin system\n\n\n## What? How?\n\nThe proxy uses asymmetric cryptography (a public and private key pair) and [JWTs](https://jwt.io) to encode its state into the magic token.\n\nEach magic token is a simple JWT signed by the proxy's *private key* with these claims:\n\n```\n{\n  \"iat\": 1541616032,\n  \"exp\": 1699296032,\n  \"token\": \"[long encrypted key]\",\n  \"allowed\": [\n    \"GET /user\",\n    \"GET /repos/theacodes/nox/issues\"\n  ]\n}\n```\n\nThe `token` claim is an encrypted version of the raw API token. It's encrypted using the proxy's **public key**, so that only the proxy itself can decrypt it (using its **private** key).\n\nThe allowed claim determines what the magic token has access to. This proxy has a basic, rudimentary scope implementation described below\n\nThe JWT is generated and signed by the proxy itself using its **private key**. This means the contents can not be tampered with without invalidating the JWT.\n\n\n## Scoping\n\nBy default, this proxy has a simple scope strategy using the format:\n\n```\nMETHOD /url/pattern\n```\n\nWhere `METHOD` can be `GET`, `POST`, `PUT`, etc. and `/url/pattern` can be any regular expression that's used to check the URL.\n\nFor instance, to create a token that has access to any repository's issues in `someorg`, you could do:\n\n```\nGET /repos/someorg/.+?/issues\n```\n\n\n## Usage\n\nTODO\n\n\n## Disclaimer\n\nThis is was adaptaed from an unofficial inside-Google project, experimental. This is not a magic bullet for security. You assume all risks when using this project.\n",
    "bugtrack_url": null,
    "license": "",
    "summary": "A stateless API proxy",
    "version": "0.1.14",
    "split_keywords": [
        "api",
        "github",
        "proxy"
    ],
    "urls": [
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "61570146b6102468475fbf727eb574d0beefd15458664c18c6e7dbf465b77fb4",
                "md5": "0d2590367863a0de3030f856d4530009",
                "sha256": "df626f0756e62fc89e592c86d468e2a4bff9efe93cfac2a624252b6165a8a6de"
            },
            "downloads": -1,
            "filename": "magic_api_proxy-0.1.14-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "0d2590367863a0de3030f856d4530009",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.6",
            "size": 21508,
            "upload_time": "2023-03-22T21:48:09",
            "upload_time_iso_8601": "2023-03-22T21:48:09.369748Z",
            "url": "https://files.pythonhosted.org/packages/61/57/0146b6102468475fbf727eb574d0beefd15458664c18c6e7dbf465b77fb4/magic_api_proxy-0.1.14-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": "",
            "digests": {
                "blake2b_256": "de99a9ceca12836b8ca24667a2132c85beca704191dcfaf4de5103c35f94188f",
                "md5": "41dccd3384cb05af38a7362258735950",
                "sha256": "a152f14d62e631d440fa94412eb5b931b8172d72d0bdd6ebf501c5cc81a0210a"
            },
            "downloads": -1,
            "filename": "magic-api-proxy-0.1.14.tar.gz",
            "has_sig": false,
            "md5_digest": "41dccd3384cb05af38a7362258735950",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.6",
            "size": 18118,
            "upload_time": "2023-03-22T21:48:11",
            "upload_time_iso_8601": "2023-03-22T21:48:11.030967Z",
            "url": "https://files.pythonhosted.org/packages/de/99/a9ceca12836b8ca24667a2132c85beca704191dcfaf4de5103c35f94188f/magic-api-proxy-0.1.14.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2023-03-22 21:48:11",
    "github": true,
    "gitlab": false,
    "bitbucket": false,
    "github_user": "rienafairefr",
    "github_project": "magic-api-proxy",
    "travis_ci": false,
    "coveralls": true,
    "github_actions": true,
    "requirements": [],
    "lcname": "magic-api-proxy"
}
        
Elapsed time: 0.05109s