GC HTTPS API Migration
All APIs should use and require HTTPS to help guarantee confidentiality, authenticity, and integrity. HTTPS provides a stronger guarantee that a client is communicating with the real API and receiving back authentic contents. It also enhances privacy for applications and users using the API. For APIs that support cross-origin request sharing (CORS) or JSONP requests, it also ensures the requests are not blocked as mixed content. (https://w3c.github.io/webappsec-mixed-content/) All new APIs should use and require HTTPS. Rather than issue a redirect when visited over HTTP (redirects within APIs are problematic, as outlined below), the API should likely return an error message (such as the HTTP status code 403 Forbidden).
|1. Add HTTPS Support||Once a certificate has been installed, test the API over HTTPS and make any needed programming or configuration adjustments. Enable HSTS for each successful API. Publish a dedicated information and resources page to help API users migrate their content to your HTTPS secure API.|
|2. Measure HTTP and HTTPS Usage||
API statistics are key for measuring performance, seeing how others are using your API, and tracking usage over time. API usage over HTTP versus HTTPS should be tracked.
|3. Announce the deprecation||
Announce that HTTP has been deprecated at the endpoint of your API.
|4. Disable the HTTP Endpoint||
Add HTTPS Support to your APIs
Following your system development life cycle and change process, acquire and installed a certificate, test the API over HTTPS and make any needed adjustments. Update your documentation to refer only to the HTTPS endpoint. Be sure to update all code examples, client libraries, sample applications, and your own applications (if you are an integrator of your own API). Update any pages, lists, or indexes that reference your API. Mark HTTP as deprecated in your documentation and strongly recommend migrating to the HTTPS endpoint. Publish a dedicated information and resources page to help API users migrate their content to your HTTPS secure API.
Announce API HTTP Deprecation
Announce that you have deprecated the HTTP endpoint of your API. Post this to your developer hub, blog, and/or mailing list. Optionally, include a deadline. If you have a method of contacting specific API integrators, such as an email address when they signed up for an API key, contact them. You may also have a list of known API-driven projects. Search the internet, and GitHub in particular, for references to the domain name or URL of your API, and your API’s documentation. Open issues on GitHub repositories about moving to the HTTPS endpoint, or even file a pull request making the change yourself.
Measure API HTTPS Usage
API analytics are key for measuring performance, seeing how others are using your API, and tracking usage over time. You should track usage of the API over HTTP versus HTTPS. If you have a way of identifying individual integrators, such as via an API key, application secret, or other submitted value, you can monitor their usage of HTTP versus HTTPS.
Disable the API HTTP Endpoint
This entire process could take anywhere from two weeks to six months or longer. You will want to weigh how widely used your API is, how critical it is, and how quickly integrators of your API tend to make adjustments. Questions to ask at this stage:
- Does my API work over HTTPS?
- Am I recommending HTTPS for my API?
- Am I collecting useful information from API clients?
In disabling, first step is to perform a “blackout test” by turning off the HTTP endpoint for a set time period; this period is usually somewhere between a few hours and a few days. Always announce any blackout tests ahead of time, and monitor your analytics and see what complaints this test sends your way. 'Optional: Pick a deadline for when you will turn off the HTTP API and include this in your announcement.' Refer blackout complainants to your HTTPS migration resources (published page) and encourage them to migrate as soon as possible. It usually takes a few lines of code or slight configuration change for an API integrator to switch to the HTTPS endpoint of an API, so do not be discouraged by negative feedback from disabling the HTTP endpoint. If you had no complaints, try a longer blackout, such as a few days to a week. Light API users may not have noticed the change in endpoint, and therefore need more of an opportunity to fail early, rather than once permanently changed. (This is especially helpful if you have no analytics and are relying on complaints as a metric.) You can conduct multiple blackouts if your analytics show they make a good improvement the number of integrators using HTTPS over HTTP, but be mindful of diminishing returns. Once satisfied with your approach and preparation for disabling the HTTP endpoing, announce a deadline for when you will turn off the HTTP API (if you have not yet done so). You can safely enable HSTS (//link to own content above) now, but do not redirect API traffic from HTTP to HTTPS. HSTS was primarily designed for web sites and is only supported in web browsers, not clients that would be used for integrating with APIs, and is a “future-proofing” step, in case you decide to provide browser access to your API in the future. As the API will continue to serve content over both HTTP and HTTPS, clients making HTTP requests to the API will continue to work until fully disabled. On the deadline, disable the HTTP endpoint. Make an announcement, referring your previous efforts to ensure a smooth transition and to your documentation, which includes a page on the migration.
API Technical Considerations
When turning off an HTTP endpoint, return an error in the same consumable manner with which your API would typically respond. Issue a clear error message, include a hyperlink if possible, and use an appropriate HTTP status code such as 403 Forbidden.
Do not redirect HTTP to HTTPS: Redirects may break API clients as, unlike browsers, they may not be configured to automatically follow redirects. Even if they followed the redirect, many API clients will change a POST request into a GET request, breaking RESTful APIs, and introducing insecure behaviours.
This incorrect behaviour is both common and well-documented.
This is meant to apply to APIs that are RESTful or equivalent. If your API is actually a public dataset that is downloaded usually through a web browser, a redirect would likely be appropriate. (Note that HSTS could also handle this redirect for you.)
Redirecting CORS Requests: Your API may support cross-origin resource sharing (CORS) through the use of
Access-Control-Allow-Origin headers. While we recommend returning an error once an HTTP version of an API is shut down, you can optionally choose to redirect CORS requests, which is widely supported in web browsers. These web browsers will obey HSTS and the HSTS preload list, thus your choices are 1) break non-HTTPS CORS requests or 2) specially handle and redirect CORS requests.
- First determine how widespread CORS requests are, what browsers make them, and ideally, what the referring URLs are (for ease of contacting the integrator).
- Redirect to the HTTPS version of the API endpoint when the
originHTTP header is present to signify a CORS request. Note: CORS headers must be included in the redirect response, as well as the response to which the request is redirected.
- CORS GET requests will not follow a redirect in Android before version 4.4, all versions of iOS, and all versions of Safari. This also applies to an HSTS “internal” redirect. If mobile browsers are not a major user, then forcing a redirect should go pretty smoothly.
Redirecting JSONP Requests: Your API may support JSON with Padding (JSONP) requests, primarily due to users’ browsers still in use. Wherever possible, consider whether to support JSONP going forward, as it is not secure or performant. If you wish to handle all JSONP requests:
- First determine how widespread JSONP requests are, what browsers make them, and ideally, what the referring URLs are (for ease of contacting the integrator).
- Redirect to the HTTPS version of the API endpoint when the JSONP callback parameter for your API is present (usually
- Note: enabling HSTS and submitting the domain to the HSTS preload list would be enough for browsers that support the preload list.