{"id":13539435,"url":"https://github.com/quay/jwtproxy","last_synced_at":"2025-06-17T11:10:51.175Z","repository":{"id":49878664,"uuid":"53436602","full_name":"quay/jwtproxy","owner":"quay","description":"An HTTP-Proxy that adds AuthN through JWTs","archived":false,"fork":false,"pushed_at":"2021-10-26T13:18:38.000Z","size":7625,"stargazers_count":410,"open_issues_count":16,"forks_count":39,"subscribers_count":25,"default_branch":"master","last_synced_at":"2025-04-02T06:35:56.627Z","etag":null,"topics":["authentication","http-proxy","jwt","proxy","tls"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/quay.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":"code-of-conduct.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2016-03-08T18:48:54.000Z","updated_at":"2025-01-14T09:42:22.000Z","dependencies_parsed_at":"2022-08-28T13:40:20.313Z","dependency_job_id":null,"html_url":"https://github.com/quay/jwtproxy","commit_stats":null,"previous_names":["coreos-inc/hmacproxy","coreos-inc/jwtproxy","coreos/jwtproxy"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/quay/jwtproxy","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quay%2Fjwtproxy","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quay%2Fjwtproxy/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quay%2Fjwtproxy/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quay%2Fjwtproxy/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/quay","download_url":"https://codeload.github.com/quay/jwtproxy/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/quay%2Fjwtproxy/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":260346891,"owners_count":22995153,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["authentication","http-proxy","jwt","proxy","tls"],"created_at":"2024-08-01T09:01:25.874Z","updated_at":"2025-06-17T11:10:46.157Z","avatar_url":"https://github.com/quay.png","language":"Go","funding_links":[],"categories":["\u003ca id=\"1a9934198e37d6d06b881705b863afc8\"\u003e\u003c/a\u003e通信\u0026\u0026代理\u0026\u0026反向代理\u0026\u0026隧道","Go","\u003ca id=\"d03d494700077f6a65092985c06bf8e8\"\u003e\u003c/a\u003e工具"],"sub_categories":["\u003ca id=\"56acb7c49c828d4715dce57410d490d1\"\u003e\u003c/a\u003e未分类-Proxy","\u003ca id=\"b6f25145e99ea944cbb528a24afaa0be\"\u003e\u003c/a\u003eHTTP\u0026\u0026HTTPS"],"readme":"# JWT Proxy\n\n[![Docker Repository on Quay](https://quay.io/repository/quay/jwtproxy/status \"Docker Repository on Quay\")](https://quay.io/repository/quay/jwtproxy)\n\nThe JWT proxy is intended to be used as a complementary service for authenticating, and possibly authorizing requests made between services.\nThere is a forward proxy component, which can be configured to sign outgoing requests to another service, and a reverse proxy component, which can be used to authenticate incoming requests from another service.\n\n## JWT Forward Proxy\n\nThe JWT forward proxy is used to sign outgoing requests with a JWT using a private key.\n\n### Features\n\n- Append a JWT `Authorization` header containing claims about which service the request originated from, and who is the intended recipient\n- Autogenerate private signing keys, and publish the public portion to a server following the [key server specification](https://github.com/coreos-inc/jwtproxy/blob/master/jwt/keyserver/keyregistry/README.md)\n- Ability to use a preshared private key if we don't want to use autogenerated keys (useful when originating service is HA)\n- Ability to sign SSL requests using MITM SSL with configurable certificate authority\n\n### Potential Features\n\n- Ability to append static claims via config\n- Ability to read dynamic claims out of a request header and turn them into JWT claims\n\n### Limitations\n\n- When the proxy is configured to use MITM SSL, the `CONNECT` tunneling mechanism is only available to forward HTTPS requests. By default, most clients exclusively use `CONNECT` for HTTPS requests, which is 100% supported.\n\n## JWT Reverse Proxy\n\nThe JWT reverse proxy is used to verify incoming requests that were signed by the forward proxy.\n\n### Features\n\n- Ability to decode and verify JWT `Authorization` headers on incoming requests\n- Ability to verify the signature based on the specified signing key against a public key fetched from a [key server](https://github.com/coreos-inc/jwtproxy/blob/master/jwt/keyserver/keyregistry/README.md)\n- Ability to verify from a single issuer using a pre-shared public key (likely only useful for testing)\n- Ability to verify SSL requests by doing SSL termination on behalf of the upstream\n- Pluggable claims verifier interface, with bundled static claims verifier implementation\n\n### Potential Features\n\n- Ability to parse and write claims as an unforgeable header sent to the upstream\n- Load balancing among multiple upstreams\n- Ability to dial a unix socket for communication with upstream server\n- Ability to bind a unix socket for use behind another proxy/load balancer/server\n- Implementation of the claims verifier interface which loads a lua file\n\n## Usage\n\nRun with:\n\n```bash\njwtproxy -config config.yaml\n```\n\nThe configuration yaml file contains a `jwtproxy` top level config flag, which allows a single yaml file to be used to configure multiple services. The presence or absence of a signer config or verifier config block will enable the forward and reverse proxy respectively.\n\n```yaml\njwtproxy:\n  \u003cSigner Config\u003e\n\n  verifier_proxies:\n  - \u003cVerifier Config\u003e\n  - \u003cVerifier Config\u003e\n```\n\n### Examples\n\nUsage examples are provided in the [examples](examples/) folder.\n\n### Signer Config\n\nConfigures and enables the JWT forward signing proxy.\n\n```yaml\njwtproxy:\n  signer_proxy:\n    enabled: \u003cbool|true\u003e\n\n    # Addr at which to bind proxy server\n    listen_addr: \u003cstring|:8080\u003e\n    shutdown_timeout: \u003ctime.Duration|1m\u003e\n\n    # Optional key and CA certificate to forge MITM SSL certificates\n    ca_key_file: \u003cpath|nil\u003e\n    ca_crt_file: \u003cpath|nil\u003e\n\n    # Certificates to be trusted by the proxy when its MITM mechanism communicates with remotes.\n    # This is optional. Specifying it currently replaces system root certificates entirely.\n    trusted_certificates: \u003c[]string|system root certificates\u003e\n\n    # Whether the remotes' certificate chain and host name should be verified.\n    insecure_skip_verify: \u003cbool|false\u003e\n\n    signer:\n      # Signing service name\n      issuer: \u003cstring|nil\u003e\n\n      # Validity duration\n      expiration_time: \u003ctime.Duration|5m\u003e\n\n      # How much time skew we allow between signer and verifier\n      max_skew: \u003ctime.Duration|1m\u003e\n\n      # Length of random nonce values\n      nonce_length: \u003cint|32\u003e\n\n      # Registerable private key source type\n      private_key:\n        type: \u003cstring|nil\u003e\n        options: \u003cmap[string]interface{}\u003e\n```\n\n#### Autogenerated Private Key\n\nConfigures a private key source which generates key pairs automatically and publishes them to a key server.\n\n```yaml\nprivate_key:\n  type: autogenerated\n  options:\n    # How often we publish a new key\n    rotate_every: \u003ctime.Duration|12h\u003e\n\n    # Folder in which to store autogenerated keys on disk\n    key_folder: \u003cstring|~/.config/jwtproxy/\u003e\n\n    # Registerable key server and config at which to publish public keys\n    key_server:\n      type: \u003cstring|nil\u003e\n      options: \u003cmap[string]interface{}\u003e\n```\n\n#### Key Registry Key Server\n\nConfigures a key server which talks to a server which implements the key registry protocol.\n\n```yaml\nkey_server:\n  type: keyregistry\n  options:\n    # Base URL from which to access key registry endpoints.\n    registry: \u003cstring|nil\u003e\n```\n\n#### Preshared Private Key\n\nConfigures a private key source which simply uses the key files specified.\n\n```yaml\nprivate_key:\n  type: preshared\n  options:\n    # Unique identifier for the private key\n    key_id: \u003cstring|nil\u003e\n\n    # Location of PEM encoded private key file\n    private_key_path: \u003cpath|nil\u003e\n```\n\n### Verifier Config\n\nConfigures and enables one or more JWT verifying reverse proxyies.\n\n```yaml\njwtproxy:\n  verifier_proxies:\n  - enabled: \u003cbool|true\u003e\n\n    # Addr at which to listen for requests\n    # It can either be an HTTP(s) URL or an UNIX socket path prefixed by 'unix:'\n    listen_addr: \u003cstring|:8081\u003e\n    shutdown_timeout: \u003ctime.Duration|1m\u003e\n\n    # Optional PEM private key and certificate files for SSL termination\n    key_file: \u003cpath|nil\u003e\n    crt_file: \u003cpath|nil\u003e\n\n    verifier:\n      # Upstream server to which to forward requests\n      # It can either be an HTTP(s) URL or an UNIX socket path prefixed by 'unix:'\n      upstream: \u003cstring|nil\u003e\n\n      # Required value for audience claim,\n      # Usually our advertised protocol and hostname\n      audience: \u003cstring|nil\u003e\n\n      # How much time skew we allow between signer and verifier\n      max_skew: \u003ctime.Duration|1m\u003e\n\n      # Maximum total amount of time for which a JWT can be signed\n      max_ttl: \u003ctime.Duration|5m\u003e\n\n      # Registerable key server type and options used to fetch\n      # public keys for verifying signatures\n      key_server:\n         type: \u003cstring|nil\u003e\n         options: \u003cmap[string]interface{}\u003e\n\n      # Registerable type and options where we track used nonces\n      nonce_storage:\n        type: \u003cstring|nil\u003e\n        options: \u003cmap[string]interface{}\u003e\n```\n\n#### Key Registry Key Server\n\nConfigures a key server which fetches public keys from a server which implements the key registry protocol.\n\n```yaml\nkey_server:\n  type: keyregistry\n  options:\n    # Base URL from which to access key registry endpoints.\n    registry: \u003cstring|nil\u003e\n\n    # Optional cache config to alleviate load on the key server.\n    cache:\n      # How long the keys stay valid in the cache\n      duration: \u003ctime.Duration|10m\u003e\n\n      # How often expired keys are removed from memory\n      purge_interval: \u003ctime.Duration|1m\u003e\n```\n\n#### Preshared Key Server (Testing Only)\n\nConfigures a local preshared mock key server which can return one and only one public key. This should probably be used **only for testing**.\n\n```yaml\nkey_server:\n  type: preshared\n  options:\n    # Configures the only issuer we will allow\n    issuer: \u003cstring|nil\u003e\n\n    # Unique ID of the only key from which we validate requests\n    key_id: \u003cstring|nil\u003e\n\n    # File path to the PEM encoded public key to verify signatures\n    public_key_path: \u003cpath|nil\u003e\n```\n\n#### Local Nonce Storage\n\nConfigures nonce storage which stores previously seen nonces in a TTL cache in memory.\n\n```yaml\nnonce_storage:\n  type: local\n  options:\n    # How often we run the cache janitor to clean up expired nonces\n    purge_interval: \u003ctime.Duration|0\u003e\n```\n\n\n### Generate keys\n\n## Generate forward proxy's CA certificate and private key\n\nWhen it comes to sign HTTPs requests, the forward proxy must *hijack* connections and act as a man-in-the-middle.\nTherefore, the proxy requires a CA certificate and private key in order to forge TLS/SSL certificates on behalf on the remote HTTPs server.\nIf none are specified, the forward proxy will throw a warning at startup and refuse to proxy HTTPs requests.\n\nThe following commands generate both, valid for a year, without any passphrase (otherwise, the proxy would require us to type it).\n\n```\nopenssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout ca.key -out ca.crt\n```\n\nThe certificate then has to be distributed and trusted by every clients that goes through the forward proxy.\nThe private key must remain secret.\n\nThe CA certificate and private key should be specified using the `ca_key_file` and `ca_crt_file` parameters in the [Signer configuration](#signer-config).\n\n## Generate reverse proxy's key pair\n\nTo confirm reverse proxy's authenticity and to guarantee confidentiality and integrity of the exchanged data, the reverse proxy can terminate TLS/SSL using a public/private key pair.\nThe key pair could either be provided by a trusted certificate authority or self-signed using the commands below:\n\n```\nopenssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout reverseProxy.key -out reverseProxy.crt\n```\n\nNote that to the question `Common Name (e.g. server FQDN or YOUR name)`, you must write the host that you expect to use for the reverse proxy.\n\nThe key pair should be specified using the `key_file` and `crt_file` parameters in the [Verifier configuration](#verifier-config).\nAlso, because the key pair is self-signed, the certificate must be trusted by the forward proxy. This can be done by trusting the certificate system-wide or by specifying it using the `trusted_certificates` list parameter in the [Signer configuration](#signer-config).\n\n\n## Build Linux Binary\n\n```\ndocker build -t jwtproxy .\ndocker run -it --rm -v \"$PWD/bin\":/go/bin -w /go --entrypoint /bin/bash jwtproxy -c \"go install -v github.com/quay/jwtproxy/cmd/jwtproxy\"\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquay%2Fjwtproxy","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fquay%2Fjwtproxy","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fquay%2Fjwtproxy/lists"}