{"id":25553907,"url":"https://github.com/docusign/blog-create-a-cors-gateway","last_synced_at":"2026-01-27T14:31:36.844Z","repository":{"id":73373170,"uuid":"132354853","full_name":"docusign/blog-create-a-CORS-gateway","owner":"docusign","description":"Instructions and configuration files for creating CORS gateways for DocuSign Single Page Applications.","archived":false,"fork":false,"pushed_at":"2021-03-07T07:43:01.000Z","size":11,"stargazers_count":2,"open_issues_count":0,"forks_count":2,"subscribers_count":10,"default_branch":"master","last_synced_at":"2025-05-31T03:44:09.930Z","etag":null,"topics":["blog","cors","cors-gateway","docusign","example-project"],"latest_commit_sha":null,"homepage":null,"language":null,"has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/docusign.png","metadata":{"files":{"readme":"README.md","changelog":null,"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,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2018-05-06T16:08:53.000Z","updated_at":"2021-11-14T17:11:13.000Z","dependencies_parsed_at":null,"dependency_job_id":"b9637606-c408-4526-973c-d5050f264dc2","html_url":"https://github.com/docusign/blog-create-a-CORS-gateway","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/docusign/blog-create-a-CORS-gateway","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fblog-create-a-CORS-gateway","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fblog-create-a-CORS-gateway/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fblog-create-a-CORS-gateway/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fblog-create-a-CORS-gateway/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/docusign","download_url":"https://codeload.github.com/docusign/blog-create-a-CORS-gateway/tar.gz/refs/heads/master","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/docusign%2Fblog-create-a-CORS-gateway/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28815047,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-01-27T12:25:15.069Z","status":"ssl_error","status_checked_at":"2026-01-27T12:25:05.297Z","response_time":168,"last_error":"SSL_read: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["blog","cors","cors-gateway","docusign","example-project"],"created_at":"2025-02-20T12:03:15.241Z","updated_at":"2026-01-27T14:31:36.839Z","avatar_url":"https://github.com/docusign.png","language":null,"funding_links":[],"categories":[],"sub_categories":[],"readme":"# Creating Apache CORS Gateways for DocuSign\n\nThis repository provides step by step instructions for\ncreating private CORS gateways for use with\nDocuSign.\n\nThis repository accompanies the DocuSign Developer blog post\n[Building Single-Page Applications with DocuSign and CORS: Part 2](https://www.docusign.com/blog/dsdev-building-single-page-applications-with-docusign-and-cors-part-2/). See the blog post for additional information.\n\n## Summary\nYou'll set up two CORS proxies/gateways, one for demo.docusign.net, and one\nfor account-d.docusign.com. The account-d server is used to lookup\nthe user's account(s) and other details\nvia the\n[userinfo](https://developers.docusign.com/esign-rest-api/guides/authentication/user-info-endpoints)\nmethod after they login. The OAuth Implicit Grant flow itself uses redirects, CORS is not needed.\n\n You’ll create two HTTPS CORS gateways:\n * `https://cors-a.worldwidecorp.us` will forward to `https://account-d.docusign.com`.\n   As noted above, this gateway will only be used for the userinfo API method.\n * `https://cors-d.worldwidecorp.us` will forward to `https://demo.docusign.net`\n\nBoth will use port 1443. You can use a different port if you'd like.\n\nIn these examples, the domain name `worldwidecorp.us` is used;\nyou will substitute your server's dns address.\nIt can include subdomain names. Eg `cors-d.my-sub-domain.mycompany.com`\n\nBoth proxies will run on one instance of Apache as two virtual hosts.\nThe proxies use port 1443 and SSL/TLS.\nThe proxies can be installed behind your firewall,\non your private network,\nor on the public Internet but they do need to be reachable by the\nbrowsers that will be running your web application.\n\n## Audience\nThese instructions are written for an experienced system and network\nadministrator. If you have questions about the\ninstructions, please consult [ServerFault](https://serverfault.com/).\n\n## Information Security\nA CORS gateway is *literally* a\n[Man in the Middle](https://en.wikipedia.org/wiki/Man-in-the-middle_attack) machine.\nIt **must** be properly configured and monitored to\nprevent a loss of **all** of your application's data.\n\nYou **must** consult with your Information Security\ndepartment or consultant to create a secure gateway.\nThese instructions do **not** provide information\non Information Security-related issues or settings.\n\nSee the [LICENSE](LICENSE) file for additional information.\n\n## Installation\n\n#### 1. Set up the two host names in the DNS system to enable access by the clients.\n\nEg `cors-d.mycompany.com` and `cors-a.mycompany.com`.\nBoth addresses need their DNS records to resolve to your Apache server.\n\n#### 2. Set up Apache on your server.\nThese examples have been tested on a Linux host. Use similar steps for Windows OS.\n\n1. Install Apache version 2.4 (or later) on your server. It may already be installed.\nConsult the instructions for your operating system for specific\ninstallation steps. You do not need to install PHP or other\nlanguage support for the CORS gateways.\n\n1. Enable Apache to restart when the system is rebooted. The commands\n   for doing this vary depending on your operating system.\n   Reboot your server and check that Apache was restarted automatically.\n\n1. Enable additional modules:\n\n   `a2enmod ssl rewrite headers proxy_http setenvif cache`\n\n   Depending on your operating system, you may need to run\n   the command as root or as the administrator.\n\n1. Restart Apache. The command for restarting Apache will vary\n   depending on your operating system. For many Linux systems the\n   restart command is\n\n   `sudo apachectl start`\n\n#### 3. Add the HTTP virtual host configuration files\nThe HTTP virtual host files will only be used by the Let's Encrypt software\nto create the SSL hosts.\n\n1. Copy files `100-cors_a.conf` and `110-cors_d.conf`\n   from this repository to the `apache2/sites-available` configuration\n   directory. Note: the configuration files are named\n   **...cors_a** and **...cors_b** (with underscore characters)\n   due to Apache restrictions for configuration file names. The\n   websites are **cors-a** and **cors-b**.\n1. Update the `ServerName` directives in both files.\n1. Create the webroot directories listed in the two files:\n   * `/var/www/cors-a`\n   * `/var/www/cors-d`\n\n   Ensure that the Apache `user` and/or `group` has access to the\n   directories. The Apache user and group are listed in the\n   main Apache configuration file, `apache2.conf`. If environment\n   variables are used, check the file `envvars` in the Apache2\n   configuration directory.\n\n1. Enable the sites on your server:\n   * `sudo a2ensite 100-cors_a.conf`\n   * `sudo a2ensite 110-cors_d.conf`\n\n#### 4. Enable the SSL hosts\nThese steps use free SSL certificates from [Let's Encrypt](https://letsencrypt.org/)\nfor the SSL sites. If your gateways are only on your private network\nthen use an appropriate SSL/TLS certificate.\n\nTo install a Let's Encrypt certificate on Linux, use the free\n[certbot](https://certbot.eff.org/)\nprogram. You'll need your server's Linux distribution name and\nversion. See the  [instructions](https://www.cyberciti.biz/faq/find-linux-distribution-name-version-number/)\nfor determining the information.\n\nIf you receive the error `E: The value 'stretch-backports' is invalid for APT::Default-Release as such a release is not available in the sources`\nthen you need to add the correct backports to your source list.\nSee the backports [instructions](https://backports.debian.org/Instructions/#index2h2).\n\nUse the [instructions](https://certbot.eff.org/)\nto run the certbot program in apache2 mode.\n\nChoose the `No redirect` option since you'll be disabling the HTTP sites.\n\nNow examine your Apache2 `sites-available` directory. You should see two\nnew configuration files, created by the certbot utility:\n\n* 100-cors_a-le-ssl.conf\n* 110-cors_d-le-ssl.conf\n\n\"le\" stands for Let's Encrypt. If you check the `sites-enabled` directory,\nyou should see all four sites ready to go:\n\n* 100-cors_a.conf\n* 100-cors_a-le-ssl.conf\n* 110-cors_d.conf\n* 110-cors_d-le-ssl.conf\n\n#### 5. Update site configurations\n\n1. Disable the HTTP sites:\n   * `sudo a2dissite 100-cors_a.conf`\n   * `sudo a2dissite 110-cors_d.conf`\n\n2. Edit the `100-cors_a-le-ssl.conf` configuration file in the `sites-available` directory,\n   * Update steps 1-4 as shown within the file.\n   * Step 1: The Let's Encrypt app overwrites the port number in\n     the `VirtualHost` statement. You will need to update it to\n     the port number you want.\n   * Step 4: Set the **Access-Control-Allow-Origin** setting) to\n     **exactly** match the *scheme* (http or https), the hostname, and the\n     port of your web app's html page origin,\n     or the CORS request will fail. You can't use a wildcard here.\n3. Repeat for the `110-cors_d-le-ssl.conf` configuration file.\n\n#### 6. Add Listen directive\nTo enable port 1443, you will add a [Listen](https://httpd.apache.org/docs/2.4/bind.html)\ndirective:\n\n**Listen 1443**\n\nThe directive can only be used once within the Apache configuration files.\nYou can add it to the master httpd.conf file, or, preferably, add\nit to the **ports.conf** file in the **apache2/** configuration directory.\n\nAdd the the **Listen 1443** line after the existing **Listen 80** line.\n\n#### 7. Test your gateways, part I\n\n1. Restart Apache to use the new host configurations:\n\n   `sudo apachectl restart`\n\n    Note: The command for restarting Apache may be different on your system.\n\n    The start and restart commands for Apache include extensive\n    error checking of the configuration files.\n\n1. Test the `account-d.docusign.com` proxy with a\n   [curl](https://curl.haxx.se/) command from a different computer:\n\n   `curl https://cors-a.worldwidecorp.us:1443/oauth/userinfo`\n\n   **Note:** Remember to use your own gateway hostname and the right port number.\n\n   You **should** receive an error response since we did not\n   include an `Authorization` header. You should see a similar\n   error if you directly contact the `account-d.docusign.com` service:\n\n   `curl https://account-d.docusign.com/oauth/userinfo`\n\n1. Test the `demo.docusign.net` proxy with this\n    [curl](https://curl.haxx.se/) command from a different computer:\n\n    `curl https://cors-d.worldwidecorp.us:1443/restapi/v2/accounts/1/envelopes/2`\n\n    **Notes:** Remember to use your own hostname and the right port number.\n\n    You **should** receive an error response since we did not\n    include an `Authorization` header. You should see a similar\n    error if you directly contact the `demo.docusign.net` service:\n\n    `curl https://demo.docusign.net/restapi/v2/accounts/1/envelopes/2`\n\n#### 8. Test your gateways, part II\n\nYou're now ready to test your web page application's access\nto DocuSign via your new gateways. Remember that your\nJavaScript program must use the CORS option to communicate\nvia the gateways.\n\n#### 9. Production\nFor production, you'll need additional gateways, one for\n`account.docusign.com`, and one for each of the production\nplatforms you need to use (`www`, `na2`, `na3`, `eu`, etc).\n\n#### Problems and Solutions\n* When you restarted Apache, you should not see any error messages.\nResearching the error messages on the web will often provide solutions.\n\n* Check your Apache access and error logs for more information if the sites\naren't responding.\n\n* Apache configurations often have permissions issues. There are many\nresources available on the internet to assist you with permissions problems.\nRemember to check permissions for the parent directories of your document\ndirectories too.\n\n* Confirm that the Apache main configuration file is enabling virtual hosts.\n\n* If the host name is not found then check your dns entries, and use ping to\nconfirm that basic name lookup and networking is okay.\n\n* If the CORS request doesn't work:\n  CORS is implemented by the browser, not by the fetch or jQuery AJAX methods.\n\n  Check the browser's debugger for additional information on the problem.\n  For example, the Chrome debugger provided this error message in the debugger's console:\n\n\u003e Failed to load https://cors-d.example.com/oauth/user_info: Response to preflight request doesn't pass access control check: The 'Access-Control-Allow-Origin' header has a value 'https://localhost' that is not equal to the supplied origin. Origin 'http://localhost' is therefore not allowed access. Have the server send the header with a valid value, or, if an opaque response serves your needs, set the request's mode to 'no-cors' to fetch the resource with CORS disabled.\n\nSolution: update the `Access-Control-Allow-Origin` header value to\n**exactly** match the host value.\nIn this case, changing `https` to `http` solved the problem.\n\n##### Which HTML files can use the CORS gateways?\n\nThe example proxy host files only allow browsers\nto use the gateway if the initial HTML file was loaded from\na specific server:\n\n````\n#### Update to the hostname that hosts your webapp\nHeader always set Access-Control-Allow-Origin \"https://your_apps_host.com\"\n````\n(Lines 30-31)\n\nYou cannot create a wildcard CORS gateway since the\nCORS standard does not allow wildcard client support\nif the `Authentication` header will be proxied.\n\n[Documentation](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS#Access-Control-Allow-Credentials)\nfor the Access-Control-Allow-Credentials option.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocusign%2Fblog-create-a-cors-gateway","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fdocusign%2Fblog-create-a-cors-gateway","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fdocusign%2Fblog-create-a-cors-gateway/lists"}