Using private_context: a technical perspective

The main use case for private_context is for seamless embedding of Sidestnd into another website. For example:

  • suppose that a work identifier on Sidestnd is https://<sidestnddomain>/works/12345
  • suppose that organisation X who owns this work has purchased Sidestnd Plus and received the private context GUID abcdefgh1234
  • suppose that an internal user of X wants to access work 12345 through the following uri: https://<domainofuserX>/shared/metadata/works/12345

Then we need to embed Sidestnd in a way that is transparent to the user. Instead of installing and running software directly, it is relatively easier to embed Sidestnd into the website. This means that Sidestnd still runs on AWS, with all its benefits. The word "relatively" is used because the organisation does need to do something on their side: run a reverse proxy. One of the more common reverse proxy tools is nginx. Configuring nginx is a lot easier than installing and running a database-driven Flask site, but it is still something that needs to be done to make embedding possible.

Now suppose that organisation X has configured nginx to embed Sidestnd:

  • an end user (in organisation X) requests https://<domainofuserX>/shared/metadata/works/12345
  • domainofx nginx intercepts the request
  • nginx rewrites the path internally to /abcdefgh1234/works/12345 and proxies the request to https://<sidestnddomain>/abcdefgh1234/works/12345
    • notice the private context GUID as a prefix
  • Sidestnd nginx (on AWS) intercepts this proxied request
    • cuts the private context GUID from the path and stores the value in a cookie
    • redirects to https://<sidestnddomain>/works/12345
  • Sidestnd nginx (on AWS) processes this redirected request
    • takes the organisation GUID from the cookie
    • amends the request with an X-Customer-Context header
  • The application server (on AWS) processes the request with the proper context
  • The response is returned to organisation X's nginx
  • Organisation X nginx returns the response to the end user
    • The end user's browser URL is unchanged at https://<domainofuserX>/shared/metadata/works/12345

Notice that there are 2 different instances of nginx involved and 3 nginx interceptions in total:

  • First interception: Organisation X's nginx instance (rewrites and proxies the request);
  • Second interception: Sidestnd's nginx instance (processes GUID and sets cookie);
  • Third interception: Sidestnd's nginx instance again (processes clean URL with cookie context)

The first interception happens on organisation X's infrastructure, while the second and third occur on Sidestnd's servers.

Also notice that the connection between the 2nd and 3rd nginx interception depends on a cookie. If the user agent refuses cookies, then the rewrite will still succeed but there might be throttling / performance problems.

example nginx config file for organisation X

nginx works with config files. The following is an example custom.conf file for organisation X who wants to embed Sidestnd on their website under the path /shared/metadata. Notice that the prefix code is hardcoded in the nginx conf file as it is necessary to build the right Sidestnd URI:

server {
    listen 443 ssl;
    server_name domainofx.com;

    # SSL configuration
    ssl_certificate /etc/nginx/ssl/nginx.crt;
    ssl_certificate_key /etc/nginx/ssl/nginx.key;
    ssl_protocols TLSv1.2 TLSv1.3;

    # add resolver
    resolver 172.31.0.2 valid=300s;  # AWS VPC DNS resolver
    resolver_timeout 5s;
    #resolver 8.8.8.8;

    location /static_a7f23b9ce415/ {
proxy_pass https://sidestnd.groundworkdatamanagement.com.au/static_a7f23b9ce415/;
        # Set customer context headers
    proxy_set_header X-Customer-GUID hft2Qsf4ha6s;
proxy_set_header X-Customer-Context hft2Qsf4ha6s;
proxy_set_header X-Origin-Context "/shared/metadata";
        # Standard proxy headers
    proxy_set_header Host sidestnd.groundworkdatamanagement.com.au;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
        # SSL settings
    proxy_ssl_verify off;
proxy_ssl_server_name on;
        # Cache static files
expires 1d;
add_header Cache-Control "public, max-age=86400";
    }

location ~ ^/auth_309a6b79ac6(/.*)?$ {
   # Remove trailing slash, use $request_uri to preserve exact path
   proxy_pass https://sidestnd.groundworkdatamanagement.com.au$request_uri;

   # Ensure method and body are preserved
   proxy_method $request_method;
   proxy_pass_request_body on;

   # Your existing headers
   proxy_set_header X-Customer-GUID hft2Qsf4ha6s;
   proxy_set_header X-Customer-Context hft2Qsf4ha6s;
   proxy_set_header X-Origin-Context "/shared/metadata";
   proxy_set_header Host sidestnd.groundworkdatamanagement.com.au;  # Use actual upstream host
   proxy_set_header X-Real-IP $remote_addr;
   proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
   proxy_set_header X-Forwarded-Proto $scheme;
   proxy_set_header X-Forwarded-Host $host;  # Important for origin tracking
}

    # Main site paths
    location / {
        root /var/www/html;
        index index.html;
    }

    # Proxy /shared/metadata/ paths
location /shared/metadata/ {
    # strip off the /shared/metadata prefix
    rewrite ^/shared/metadata/(.*)$ /$1 break;

    # Set headers
    proxy_set_header X-Customer-GUID hft2Qsf4ha6s;
    proxy_set_header X-Customer-Context hft2Qsf4ha6s;
    proxy_set_header X-Origin-Context "/shared/metadata";
    proxy_set_header Host sidestnd.groundworkdatamanagement.com.au;
    proxy_set_header X-Real-IP $remote_addr;
    proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
    proxy_set_header X-Forwarded-Proto $scheme;
    proxy_set_header X-Forwarded-Host $host;

    # Forward to upstream server
    proxy_pass https://sidestnd.groundworkdatamanagement.com.au;

    # SSL settings - CRITICAL for Elastic Beanstalk
    proxy_ssl_verify off;
    proxy_ssl_server_name on;
    proxy_ssl_name sidestnd.groundworkdatamanagement.com.au;

    # Use HTTP/1.1 for better compatibility
    proxy_http_version 1.1;
    proxy_set_header Connection "";

    # Adjust timeouts
    proxy_connect_timeout 30s;
    proxy_send_timeout 30s;
    proxy_read_timeout 30s;

    # Handle cookies
    proxy_cookie_domain sidestnd.groundworkdatamanagement.com.au 3.106.249.9;
    proxy_cookie_path / /shared/metadata/;
}


}
# HTTP server to redirect to HTTPS
server {
    listen 80;
    server_name 3.106.249.9;

    # Redirect all HTTP requests to HTTPS
    location / {
        return 301 https://$host$request_uri;
    }
}

Notice that the private context GUID value is hardcoded. The path /shared/metadata is for illustrative purposes.

Using the organisation GUID as a prefix allows for scoped access to specific content - namely the works that X has published on Sidestnd.

There are alternatives to nginx that provide the same functionality, such as Apache.