Перейти к содержанию

gps-license: GetPageSpeed license and update-telemetry module

Debian/Ubuntu installation

These docs apply to the APT package nginx-module-gps-license provided by the GetPageSpeed Extras repository.

  1. Configure the APT repository as described in APT repository setup.
  2. Install the module:
sudo apt-get update
sudo apt-get install nginx-module-gps-license

Warning

This module is not yet published as nginx-module-gps-license in the APT repositories. Stay tuned, or email [email protected] to request it.


GetPageSpeed License Module for nginx. Validates JWT-based license tokens, reports usage telemetry, and exposes license state via nginx variables.

Overview

This module provides license validation for nginx-mod packages distributed via GetPageSpeed. It supports:

  • JWT token validation with RS256 signatures
  • Shared memory caching of license state
  • Grace period for expired licenses (90 days)
  • Soft/footer/hard enforcement modes
  • nginx variables for license status

Note: Usage telemetry reporting is planned for a future version.

Configuration

Directives

gps_license_zone

Syntax: gps_license_zone zone=name:size Context: http Default: —

Defines shared memory zone for caching license state.

http {
    gps_license_zone zone=license:1m;
}

gps_license

Syntax: gps_license on | off Context: http, server, location Default: off

Enables license checking for requests.

gps_license_token

Syntax: gps_license_token path | env:VAR_NAME Context: http Default: —

Path to JWT token file or environment variable name.

gps_license_token /etc/nginx/license.jwt;
## OR
gps_license_token env:GPS_LICENSE_TOKEN;

gps_license_enforcement

Syntax: gps_license_enforcement soft | footer | hard Context: http, server, location Default: soft

Enforcement mode: - soft: Log warnings, continue serving traffic - footer: Continue serving traffic, but append a visible GetPageSpeed notice to unlicensed text/html responses (free-trial watermark). The footer disappears as soon as a valid license token is installed. Responses that are pre-compressed upstream (Content-Encoding set), non-HTML, non-200, or subrequests are never touched. Locally produced gzip is fine — the filter runs before the gzip filter. - hard: Return 503 with error details

The backend report response may override the configured mode (field enforcement: "soft" | "footer" | "hard"); a backend-pushed value takes precedence over local config until the next restart.

gps_license_report_endpoint

Syntax: gps_license_report_endpoint url Context: http Default: https://www.getpagespeed.com/wp-json/getpagespeed/v1/license/report

URL for usage reporting (not yet implemented).

gps_license_report_interval

Syntax: gps_license_report_interval time Context: http Default: 1h

Interval between usage reports (not yet implemented).

gps_license_grace_period

Syntax: gps_license_grace_period time Context: http Default: 90d

Grace period after license expiration.

Variables

Variable Description
$gps_license_valid "1" if valid or in grace, "0" otherwise
$gps_license_tier License tier ("ultra", "plus", "standard")
$gps_license_expires Expiration timestamp
$gps_license_grace "1" if in grace period, "0" otherwise
$gps_license_enforcement Current enforcement mode

Example Configuration

http {
    gps_license_zone zone=license:1m;

    server {
        listen 80;
        server_name example.com;

        gps_license on;
        gps_license_token /etc/nginx/license.jwt;
        gps_license_enforcement soft;

        # Log license state
        log_format license '$remote_addr - $gps_license_tier [$gps_license_valid]';

        location / {
            root /var/www/html;

            # Add license header for debugging
            add_header X-License-Tier $gps_license_tier;
        }
    }
}

Error Responses

When gps_license_enforcement hard and license is invalid:

HTTP 503 with headers: - X-GPS-License-Error: missing|invalid|expired|revoked

Response body:

GetPageSpeed License Error: expired

Your nginx-mod license is not valid.
Visit https://www.getpagespeed.com/repo-subscribe to get a license.

JWT Token Format

Tokens are signed with RS256 and contain:

{
  "iss": "getpagespeed.com",
  "aud": "nginx-mod",
  "sub": "I-XXXXXXXXX",
  "exp": 1234567890,
  "tier": "ultra",
  "jti": "uuid-v4",
  "client_id": 12345,
  "features": {
    "reposync_allowed": true
  }
}

Public Key

The RSA public key is embedded at compile time. Key rotation requires module rebuild.

Important Notes

nginx Request Phases

The license module runs in the ACCESS_PHASE. Some nginx directives run in earlier phases and will bypass license checking:

  • return and rewrite ... last run in REWRITE_PHASE (before ACCESS_PHASE)
  • error_page redirects may bypass the check

For license enforcement to work, use content handlers like proxy_pass, fastcgi_pass, try_files, or static file serving with root/alias.

## WRONG - return runs before license check
location / {
    gps_license on;
    gps_license_enforcement hard;
    return 200 "OK";  # Bypasses license check!
}

## CORRECT - static files trigger ACCESS_PHASE
location / {
    gps_license on;
    gps_license_enforcement hard;
    root /var/www/html;
}

## CORRECT - proxy_pass triggers ACCESS_PHASE
location / {
    gps_license on;
    gps_license_enforcement hard;
    proxy_pass http://backend;
}

gps_license_token Location

The gps_license_token directive must be in the http {} block (not in server or location blocks) because license validation happens once at worker startup, not per-request.