{"id":28500913,"url":"https://github.com/kaltura/nginx-secure-token-module","last_synced_at":"2025-07-04T12:30:53.323Z","repository":{"id":23392101,"uuid":"26753890","full_name":"kaltura/nginx-secure-token-module","owner":"kaltura","description":null,"archived":false,"fork":false,"pushed_at":"2024-03-03T07:59:40.000Z","size":227,"stargazers_count":115,"open_issues_count":19,"forks_count":40,"subscribers_count":37,"default_branch":"master","last_synced_at":"2025-06-08T15:08:01.383Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"agpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/kaltura.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2014-11-17T11:34:16.000Z","updated_at":"2025-04-17T17:09:02.000Z","dependencies_parsed_at":"2024-03-03T08:43:51.528Z","dependency_job_id":null,"html_url":"https://github.com/kaltura/nginx-secure-token-module","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/kaltura/nginx-secure-token-module","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaltura%2Fnginx-secure-token-module","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaltura%2Fnginx-secure-token-module/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaltura%2Fnginx-secure-token-module/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaltura%2Fnginx-secure-token-module/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/kaltura","download_url":"https://codeload.github.com/kaltura/nginx-secure-token-module/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/kaltura%2Fnginx-secure-token-module/sbom","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":263539064,"owners_count":23477454,"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":[],"created_at":"2025-06-08T15:08:01.018Z","updated_at":"2025-07-04T12:30:53.317Z","avatar_url":"https://github.com/kaltura.png","language":"C","funding_links":[],"categories":["Authentication"],"sub_categories":[],"readme":"# Secure token module for Nginx [![Build Status](https://travis-ci.org/kaltura/nginx-secure-token-module.svg?branch=master)](https://travis-ci.org/kaltura/nginx-secure-token-module)\n\nGenerates CDN tokens, either as a cookie or as a query string parameter (m3u8,mpd,f4m only).\nCurrently supports Akamai v2 tokens, and Amazon CloudFront tokens.\nIn addition, the module supports the encryption of URIs with a configured key.\n\n## Build\n\nTo link statically against nginx, cd to nginx source directory and execute:\n\n    ./configure --add-module=/path/to/nginx-secure-token-module\n\nTo compile as a dynamic module (nginx 1.9.11+), use:\n  \n\t./configure --add-dynamic-module=/path/to/nginx-secure-token-module\n\nIn this case, the `load_module` directive should be used in nginx.conf to load the module.\n\nRequires OpenSSL.\n\n## Configuration\n\n### Generic token parameters\n\n#### secure_token\n* **syntax**: `secure_token value`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nSets the value of the token that should be embedded in the manifest/returned as a cookie.\nThe parameter value can contain variables, and often points to variables set by this module\n(using `secure_token_akamai` / `secure_token_cloudfront` blocks)\n\n#### secure_token_avoid_cookies\n* **syntax**: `secure_token_avoid_cookies on/off`\n* **default**: `on`\n* **context**: `http`, `server`, `location`\n\nWhen enabled the module prefers to use a query string token instead of a cookie token.\nA query string token is currently supported only for the following mime types (other mime types return a cookie token):\n* application/vnd.apple.mpegurl\n* application/dash+xml\n* video/f4m\n\n#### secure_token_types\n* **syntax**: `secure_token_types mime_type ...`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nDefines a set of mime types that should return a token\n\n#### secure_token_uri_filename_prefix\n* **syntax**: `secure_token_uri_filename_prefix prefix`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nDefines a set of prefixes that will be matched against the URI file name, only URIs whose file name\nstarts with one of the defined prefixes will return a token\n\n#### secure_token_expires_time\n* **syntax**: `secure_token_expires_time time`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nSets the expiration time of responses that are not tokenized \n(determines the values of the Cache-Control and Expires HTTP headers)\n\n#### secure_token_cookie_token_expires_time\n* **syntax**: `secure_token_cookie_token_expires_time time`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nSets the expiration time of responses that are tokenized with a cookie token \n(determines the values of the Cache-Control and Expires HTTP headers)\n\n#### secure_token_query_token_expires_time\n* **syntax**: `secure_token_query_token_expires_time time`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nSets the expiration time of responses that are tokenized with a query string token \n(determines the values of the Cache-Control and Expires HTTP headers)\n\n#### secure_token_cache_scope\n* **syntax**: `secure_token_cache_scope scope`\n* **default**: `public`\n* **context**: `http`, `server`, `location`\n\nSets the cache scope (public/private) of responses that are not tokenized\n\n#### secure_token_token_cache_scope\n* **syntax**: `secure_token_token_cache_scope scope`\n* **default**: `private`\n* **context**: `http`, `server`, `location`\n\nSets the cache scope (public/private) of responses that are tokenized (query / cookie)\n\n#### secure_token_last_modified\n* **syntax**: `secure_token_last_modified time`\n* **default**: `Sun, 19 Nov 2000 08:52:00 GMT`\n* **context**: `http`, `server`, `location`\n\nSets the value of the last-modified header of responses that are not tokenized.\nAn empty string leaves the value of last-modified unaltered, while the string \"now\" sets the header to the server current time.\n\n#### secure_token_token_last_modified\n* **syntax**: `secure_token_token_last_modified time`\n* **default**: `now`\n* **context**: `http`, `server`, `location`\n\nSets the value of the last-modified header of responses that are tokenized (query / cookie)\nAn empty string leaves the value of last-modified unaltered, while the string \"now\" sets the header to the server current time.\n\n#### secure_token_content_type_m3u8\n* **syntax**: `secure_token_content_type_m3u8 type`\n* **default**: `application/vnd.apple.mpegurl`\n* **context**: `http`, `server`, `location`\n\nSets the content type that should be parsed as m3u8 for token insertion\n\n#### secure_token_content_type_mpd\n* **syntax**: `secure_token_content_type_mpd type`\n* **default**: `application/dash+xml`\n* **context**: `http`, `server`, `location`\n\nSets the content type that should be parsed as mpd for token insertion\n\n#### secure_token_content_type_f4m\n* **syntax**: `secure_token_content_type_f4m type`\n* **default**: `video/f4m`\n* **context**: `http`, `server`, `location`\n\nSets the content type that should be parsed as f4m for token insertion\n\n### Akamai token parameters\n\n#### secure_token_akamai\n* **syntax**: `secure_token_akamai $variable { ... }`\n* **context**: `http`\n\nCreates a new variable whose value is an Akamai token, created according to the \nparameters specified within the block.\n\nThe block supports the following parameters:\n\n#### key\n* **syntax**: `key key_hex`\n* **default**: `N/A (mandatory)`\n\nSets the secret key.\n\n#### param_name\n* **syntax**: `param_name name`\n* **default**: `__hdnea__`\n\nSets the token parameter name (either the name of the cookie or the query string parameter)\n\n#### acl\n* **syntax**: `acl acl`\n* **default**: `$secure_token_baseuri_comma`\n\nSets the signed part of the URL (ACL). The parameter value can contain variables.\n\n#### start\n* **syntax**: `start time`\n* **default**: `0`\n\nSets the start time of the token (see `Time format` below)\n\n#### end\n* **syntax**: `end time`\n* **default**: `86400`\n\nSets the end time of the token (see `Time format` below)\n\n#### ip_address\n* **syntax**: `ip_address address`\n* **default**: `none`\n\nSets the IP address that should be embedded in the token.\nThe parameter value can contain variables, e.g. $remote_addr.\n\n### CloudFront token parameters\n\n#### secure_token_cloudfront\n* **syntax**: `secure_token_cloudfront $variable { ... }`\n* **context**: `http`\n\nCreates a new variable whose value is a CloudFront token, created according to the \nparameters specified within the block.\n\nThe block supports the following parameters:\n\n#### private_key_file\n* **syntax**: `private_key_file filename`\n* **default**: `N/A (mandatory)`\n\nSets the file name of the private key (PEM file)\n\n#### key_pair_id\n* **syntax**: `key_pair_id id`\n* **default**: `N/A (mandatory)`\n\nSets the key pair id\n\n#### acl\n* **syntax**: `acl acl`\n* **default**: `$secure_token_baseuri_comma`\n\nSets the signed part of the URL (ACL). The parameter value can contain variables.\n\n#### end\n* **syntax**: `end time`\n* **default**: `86400`\n\nSets the end time of the token (see `Time format` below)\n\n#### ip_address\n* **syntax**: `ip_address address`\n* **default**: `none`\n\nSets the IP address that should be embedded in the token.\nThe parameter value can contain variables, e.g. $remote_addr/32 can be used to limit the token to the specific IP of the client.\n\n### Broadpeak token parameters\n\n#### secure_token_broadpeak\n* **syntax**: `secure_token_broadpeak $variable { ... }`\n* **context**: `http`\n\nCreates a new variable whose value is a Broadpeak token, created according to the\nparameters specified within the block.\n\nThe block supports the following parameters:\n\n#### key\n* **syntax**: `key key`\n* **default**: `N/A (mandatory)`\n\nSets the secret key. The parameter value can contain variables.\n\n#### param_name\n* **syntax**: `param_name name`\n* **default**: `token`\n\nSets the token parameter name (either the name of the cookie or the query string parameter)\n\n#### acl\n* **syntax**: `acl acl`\n* **default**: `$secure_token_baseuri_comma`\n\nSets the signed part of the URL (ACL). The parameter value can contain variables.\n\n#### start\n* **syntax**: `start time`\n* **default**: `0`\n\nSets the start time of the token (see `Time format` below)\n\n#### end\n* **syntax**: `end time`\n* **default**: `86400`\n\nSets the end time of the token (see `Time format` below)\n\n#### session_start\n* **syntax**: `session_start time`\n* **default**: `N/A`\n\nSets the start time of the session, required for catchup. The parameter value can contain variables.\n\n#### session_end\n* **syntax**: `session_end time`\n* **default**: `N/A`\n\nSets the end time of the session, required for catchup. The parameter value can contain variables.\n\n#### additional_querylist\n* **syntax**: `additional_querylist expr`\n* **default**: `N/A`\n\nSets the primary token value, the value needs to be a list of name=value pairs without any separator.\nFor example, \"ip=${arg_ip}account=${arg_account}device=${arg_device}\".\nThe parameter value can contain variables.\n\n### URI encryption parameters\n\n#### secure_token_encrypt_uri\n* **syntax**: `secure_token_encrypt_uri on/off`\n* **default**: `off`\n* **context**: `http`, `server`, `location`\n\nEnables/disables uri encryption\n\n#### secure_token_encrypt_uri_key\n* **syntax**: `secure_token_encrypt_uri_key key_hex`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nSets the encryption key, the key has to be 256 bits (64 hex characters)\n\n#### secure_token_encrypt_uri_iv\n* **syntax**: `secure_token_encrypt_uri_iv iv_hex`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nSets the encryption iv, the iv has to be 128 bits (32 hex characters)\n\n#### secure_token_encrypt_uri_part\n* **syntax**: `secure_token_encrypt_uri_part expression`\n* **default**: `none`\n* **context**: `http`, `server`, `location`\n\nAn expression that calculates the part of the URL that should be encrypted in regular expression locations.\nFor non-regular expression locations, the encrypted part is everything following the path defined on the location block.\n\nExample 1:\n```\n  location /secret_param/([^/]+)/some_other_param/.* {\n  \tsecure_token_encrypt_uri_part $1;\n\t...\n  }\n```\n  In this configuration, only the value of secret_param will be encrypted/decrypted.\n\nExample 2:  \n```\n  location /base/ {\n    ...\n  }\n```\n  In this configuration, everything following /base/ will be encrypted/decrypted.\n  \n#### secure_token_encrypt_uri_hash_size\n* **syntax**: `secure_token_encrypt_uri_hash_size size`\n* **default**: `8`\n* **context**: `http`, `server`, `location`\n\nThe size in bytes of hash used to validate the uri after decryption, the value has to be between 0 and 16.\n\n### Time format\n\nSome of the configuration parameters mentioned above, support both absolute timestamps,\nand timestamps relative to `now`.\nThese parameters can be set in the configuration using one of the following formats:\n* `epoch` - unix timestamp 0 (01/01/1970)\n* `max` - unix timestamp 2147483647 (18/01/2038)\n* `@1481230000` - unix timestamp 1481230000 (8/12/2016)\n* `10d` / `+10d` - `now` + 10 days\n* `-5m` - `now` - 5 minutes\n\n## Sample configurations\n\n### HLS packaging with Akamai tokens\n```\n\tsecure_token_akamai $token {\n\t\tkey 1234;\n\t\tacl \"$secure_token_baseuri_comma*\";\n\t}\n\n\tserver {\n\t\n\t\tlocation ~ ^/hls/p/\\d+/(sp/\\d+/)?serveFlavor/ {\n\t\t\tvod hls;\n\n\t\t\tg2o        on;\n\n\t\t\tsecure_token $token;\n\t\t\tsecure_token_types application/vnd.apple.mpegurl;\n\t\t\t\n\t\t\tsecure_token_expires_time 100d;\n\t\t\tsecure_token_query_token_expires_time 1h;\n\n\t\t\tmore_set_headers 'Access-Control-Allow-Headers: *';\n\t\t\tmore_set_headers 'Access-Control-Expose-Headers: Server,range,Content-Length,Content-Range';\n\t\t\tmore_set_headers 'Access-Control-Allow-Methods: GET, HEAD, OPTIONS';\n\t\t\tmore_set_headers 'Access-Control-Allow-Origin: *';\n\t\t}\n\t\t\n\t}\n```\n\n### HDS packaging with CloudFront tokens\n```\n\tsecure_token_cloudfront $token {\n\t\tprivate_key_file /path/to/pem;\n\t\tkey_pair_id ABCDEF;\n\t\tacl \"$scheme://$http_host$secure_token_baseuri_comma*\";\n\t}\n\n\tserver {\n\t\n\t\tlocation ~ ^/hds/p/\\d+/(sp/\\d+/)?serveFlavor/ {\n\t\t\tvod hds;\n\t\t\tvod_segment_duration 6000;\n\t\t\tvod_align_segments_to_key_frames on;\n\t\t\tvod_segment_count_policy last_rounded;\n\n\t\t\tsecure_token $token;\n\t\t\tsecure_token_types video/f4m;\n\t\t\t\n\t\t\tsecure_token_expires_time 100d;\n\t\t\tsecure_token_query_token_expires_time 1h;\n\n\t\t\tmore_set_headers 'Access-Control-Allow-Headers: *';\n\t\t\tmore_set_headers 'Access-Control-Expose-Headers: Server,range,Content-Length,Content-Range';\n\t\t\tmore_set_headers 'Access-Control-Allow-Methods: GET, HEAD, OPTIONS';\n\t\t\tmore_set_headers 'Access-Control-Allow-Origin: *';\n\t\t}\n\t\t\n\t}\n```\n\n### Encrypted HLS with token security on the encryption key\n\nThis configuration enables token security while having static URLs for the video segments,\nthis enables the caching of the segments transparently by proxies.\n```\n\tsecure_token_akamai $token {\n\t\tkey 1234;\n\t\tacl \"$secure_token_baseuri_comma*\";\n\t}\n\n\tserver {\n\t\n\t\tlocation ~ ^/s/hls/enc/p/\\d+/(sp/\\d+/)?serveFlavor/ {\n\t\t\tvod hls;\n\t\t\tvod_secret_key \"password$vod_filepath\";\n\n\t\t\tsecure_token $token;\n\t\t\tsecure_token_types application/vnd.apple.mpegurl;\n\t\t\t\n\t\t\tsecure_token_expires_time 100d;\n\t\t\tsecure_token_query_token_expires_time 1h;\n\t\t\t\n\t\t\tsecure_token_uri_filename_prefix index;\n\t\t\tsecure_token_tokenize_segments off;\n\n\t\t\takamai_token_validate $arg___hdnea__;\n\t\t\takamai_token_validate_key 1234;\n\t\t\takamai_token_validate_uri_filename_prefix encryption;\n\t\t\takamai_token_validate_uri_filename_prefix index;\n\t\t}\n\t\t\n\t}\n```\nNote: this configuration requires the module https://github.com/kaltura/nginx-akamai-token-validate-module\nin addition to nginx-secure-token-module\n\n### Adding token security on top of an existing HDS/HLS live stream\n```\n\tsecure_token_akamai $token {\n\t\tkey 1234;\n\t\tacl \"$secure_token_baseuri_comma*\";\n\t}\n\n\tserver {\n\t\n\t\tlocation /secure-live/ {\n\t\t\tproxy_pass http://original.live.domain;\n\n\t\t\tsecure_token $token;\n\t\t\tsecure_token_types text/xml application/vnd.apple.mpegurl;\t\t\n\t\t\tsecure_token_content_type_f4m text/xml;\n\t\t\t\n\t\t\tsecure_token_expires_time 100d;\n\t\t\tsecure_token_query_token_expires_time 1h;\n\n\t\t\takamai_token_validate $arg___hdnea__;\n\t\t\takamai_token_validate_key 1234;\n\t\t\takamai_token_validate_strip_token __hdnea__;\n\t\t}\n\t\n\t}\n```\nNote: this configuration requires the module https://github.com/kaltura/nginx-akamai-token-validate-module\nin addition to nginx-secure-token-module\n\n### URI encryption\n```\n\tlocation ~ ^/hls/p/\\d+/(sp/\\d+/)?serveFlavor/entryId/([^/]+)/(.*) {\n\t\tvod hls;\n\t\tvod_secret_key \"password$2\";\n\n\t\tsecure_token_encrypt_uri on;\n\t\tsecure_token_encrypt_uri_key 000102030405060708090a0b0c0d0e0f101112131415161718191a1b1c1d1e1f;\n\t\tsecure_token_encrypt_uri_iv 00000000000000000000000000000000;\n\t\tsecure_token_encrypt_uri_part $3;\n\t\tsecure_token_types application/vnd.apple.mpegurl;\n\n\t\tadd_header Last-Modified \"Sun, 19 Nov 2000 08:52:00 GMT\";\n\t\texpires 100d;\n\t}\n```\n\n## Nginx variables\n\nThe module adds the following nginx variables:\n* `$secure_token_baseuri` - contains the value of the `$uri` built in variable truncated up to the last slash (/). \n\tFor exmaple, if `$uri` is /a/b/c.htm then `$secure_token_baseuri` will be /a/b/.\n* `$secure_token_baseuri_comma` - same as `$secure_token_baseuri`, except that if this value contains a comma (,) \n\tthe value is truncated up to the comma position.\n\tFor exmaple, if `$uri` is /a/b/c.htm then `$secure_token_baseuri_comma` will be /a/b/; \n\tif `$uri` is /a/b,c/d.htm then `$secure_token_baseuri_comma` will be /a/b.\n* `$secure_token_original_uri` - contains the original (encrypted) uri when using uri encryption.\n\tNote that the built in `$uri` variable contains the modified (decrypted) uri in this case.\n\n## Copyright \u0026 License\n\nAll code in this project is released under the [AGPLv3 license](http://www.gnu.org/licenses/agpl-3.0.html) unless a different license for a particular library is specified in the applicable library path. \n\nCopyright © Kaltura Inc. All rights reserved.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaltura%2Fnginx-secure-token-module","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fkaltura%2Fnginx-secure-token-module","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fkaltura%2Fnginx-secure-token-module/lists"}