How to run streamlit in https mode?

Is there a new approach oder workaround available with st v1.0?. It seems still to host only unsecured http sessions.

1 Like

I am sure you are aware of this, but for anyone who works with data or use cases that are at all sensitive, this is, or at least should be, a crucial requirement, both because it is common sense and good practice, and because there is a large and vociferous privacy community that is just waiting to jump on companies that ignore privacy protection. One of the first things I did at my last PM job was to move us to https.

1 Like

Streamlit as a Python library intentionally stops before https, not because we canā€™t do it, but rather so that we focus on providing the best data app experience for users.

Our Streamlit Deployment Guide (wiki) highlights several community-based solutions for using nginx or Apache2 to set up https authentication, and Streamlit Cloud is https by default.

So there are definitely ways to run your Streamlit apps securely, irrespective of the version of Streamlit you are using.

Best,
Randy

4 Likes

Hi,

The following is meant as friendly offer of a complementary perspective, not trying to bust your chops, or to argue with the near-term focus on providing best data app experience, and I totally commend Streamlit for providing good pointers to community documentation about how to deploy SSL.

Iā€™ve been acquiring, processing, creating, and distributing global data sets since the 1990s (for NASAā€™s EOSDIS) and I have learned to think about data as coming with a whole lot of intangible attributes attached other than just raw numbers. Most data comes into existence from its very first moment with terms of use, privacy considerations, copyright and security issues attached (as well as inadequate documentation, and the need to update the data). Iā€™m exaggerating, but just scribbling a few figures on a page of a lab notebook is enough to set those rights in motion. And irritatingly, terms of use, etc., are very often a real and immediate constraint that prevent people from doing interesting and magical things with data. All those issues come with people attached who care intensely about them, and for all those people, having https enabled has become just one of many ā€˜table stakesā€™ items that are expected from people who are using their data and especially making it visible via a ā€œdata appā€. And roadblocks on deploying SSL are significant obstacles for those battling through them (Iā€™ve done it dozens of time, but itā€™s always a headache). I am sure I speak for many when I wish those roadblocks would just go away. :wink:

Iā€™m guessing that as Streamlit scales, the ā€œsoftā€ issues around data will become more important, and so will the outside-the-library deployment issues. So my $0.02 is ā€œput it on the roadmap!ā€

4 Likes

Disagree. There are many more requirements, as you suggest, than just using https. There are data access, personnel, data sharing, auditingā€¦ the list is endless. HTTPS is only a single aspect of this, and may be more or less important depending on use case.

And all of these components of good data governance are difficult to do well, especially in a generic sense, without the context of the actual project.

There are many solutions to good HTTPS access, and signposting these and providing good integration is vital, but do not try to reinvent the wheel on this. A bad security implementation is a massive security risk. Focus on what you uniquely do well - streamlit explicitly NOT providing Https is much more preferable than an outdated or incomplete implementation.

Hosting on streamlit or behind a reverse proxy is trivial and allow separation of security from business logic.

My $0.02 - do NOT put it on the road map!

2 Likes

Itā€™s quite easy to run it on HTTPS with reverse proxy as madflier suggests. I have done that by configuring apache server. When the request comes to the IP, apache will receive it and forward it to the appropriate port in which streamlit is running. I then used certbot to issue the certificate and also reroute all the traffic to https. Finally, you adjust the config in streamlit to point to the correct ip address / domain name in which you are serving the app.

Since Streamlit uses Tornado you can just edit the Package to make it use HTTPS instead of HTTP by adding the following ā€œssl_optionsā€ in file ā€œserver.pyā€ in path ā€œC:\Python310\Lib\site-packages\streamlit\serverā€. And everything works fine. HTTPS gets used instead of HTTP and WebSocketSecure (WSS) gets used instead of WebSocket (WS).

8 Likes

I tried it on my server but web page does not work once I added ssl_options. Do I need any actions on top of adding ssl_options?

This worked for me but I am on a Mac so the path was slightly different. Youā€™ll want to generate an unencrypted key if your starting with a .PFX since it is password protected.

This is great.

For a networking newb like myself, I guess I have to generate those two files. How would I go about that?

Thanks

1 Like

How did u get SSL certificate for the IP address? let me say if its 145.354.346.222:8051

This works perfectly!
Anyone wondering how to get the cert file and key file refer to this, you will need a domain name for this beforehand, certificate generation will not work on the IP address directly.

The server port in ā€˜settings.tomlā€™ should be set to 443 like so. Headless just means that there will not be a popup of the app on launch.

[server]
port = 443
headless = true

The cert file is equivalent to the ā€˜fullchain.pemā€™ file and the key is equivalent to the ā€˜privkey.pemā€™ file.
Enter the paths in this path and you should be good to go.

To run the app in port 443 you may need to run as superuser.

1 Like

Oops, So no way we can get SSL for IP address to run my VPS hosted streamlit.
But thanks for the reply. Sure this conversation will prove helpful to someone.

How you create cert.cert and key.key for this?

How I can create cert.cert and key.key for this? I tried using Certbot with the ā€œcertbot certonlyā€ command, but it didnā€™t work.

How I can create cert.cert and key.key for this? I tried using Certbot with the ā€œcertbot certonlyā€ command, but it didnā€™t work.

Also you can specify a domain (if your VM has one) in ~/.streamlit/config.toml like:

[browser]
serverAddress=ā€œmydomainā€

[server]
port = 443
sslCertFile = ā€œ/etc/letsencrypt/live/mydomain/cert.pemā€
sslKeyFile = ā€œ/etc/letsencrypt/live/mydomain/privkey.pemā€

1 Like

how to use encrypted private key in streamlit app?

Iā€™ve found a simple approach to run the streamlit app in https mode:

  1. Generate temp key+cert files
    openssl req -x509 -nodes -days 365 -newkey rsa:2048 -keyout key.pem -out cert.pem
  2. Run streamlit app using generated key+cert files
    For example:
    streamlit run app.py --server.enableCORS=false --server.sslKeyFile /tmp/key.pem --server.sslCertFile /tmp/cert.pem
2 Likes

Hey Streamlit fans, i was struggling to get my app in production to due unviability of HTTPS connection.

Searching through various channels and articles, iā€™m happy to share with the community that iā€™m able to get my application working with streamlit.

One major thing many of us are missing is ā€œWebsocketsā€. Streamlit uses web sockets and hence even after reverse proxy, you canā€™t get it running simply because the websockets are not routed aptly.
You may see errors like
ā€œconnect() failed (111: Unknown error) while connecting to upstreamā€
400/404 error with /_stcore/health
400/404 error /_stcore/host-config

Hereā€™s the end to end guide for - ā€œHow to setup HTTPS connection for Streamlit applicationā€

To secure a Streamlit application using HTTPS, youā€™ll typically use a reverse proxy like Nginx, which can handle the SSL/TLS termination for you. This way, you can serve your Streamlit app over a secure connection without modifying the Streamlit server itself. Hereā€™s a step-by-step guide on setting this up using Nginx and Letā€™s Encrypt for obtaining a free SSL certificate.

Step 1: Install Nginx and Certbot

  1. Install Nginx: Depending on your operating system, you can install Nginx using the package manager. For example, on Ubuntu, you would use:
sudo apt update
sudo apt install nginx
  1. Install Certbot: Certbot is a free, open-source software tool for automatically using Letā€™s Encrypt certificates on manually-administrated websites to enable HTTPS.
sudo apt install certbot python3-certbot-nginx

Step 2: Obtain a SSL Certificate

Use Certbot to obtain an SSL certificate automatically and configure Nginx to use this certificate:

sudo certbot --nginx -d yourdomain.com

Replace yourdomain.com with your actual domain. Certbot will modify your Nginx configuration to serve content over HTTPS and set up automatic certificate renewals.

Step 3: Configure Nginx for Streamlit with WebSocket Support

Hereā€™s how to modify the Nginx configuration file to support HTTPS, including the proper handling of WebSocket connections:

server {
    listen 443 ssl;
    server_name yourdomain.com;

    ssl_certificate /etc/letsencrypt/live/yourdomain.com/fullchain.pem;
    ssl_certificate_key /etc/letsencrypt/live/yourdomain.com/privkey.pem;

    ssl_protocols TLSv1.2 TLSv1.3;
    ssl_ciphers HIGH:!aNULL:!MD5;

    location / {
        proxy_pass http://localhost:8501;
        proxy_http_version 1.1;

        # WebSocket support
        proxy_set_header Upgrade $http_upgrade;
        proxy_set_header Connection "upgrade";

        # Standard proxy headers
        proxy_set_header Host $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;
    }
}

server {
    listen 80;
    server_name yourdomain.com;
    return 301 https://$host$request_uri;  # Redirect all HTTP traffic to HTTPS
}

Key Additions for WebSocket Support:

  1. proxy_http_version 1.1;: Ensures that HTTP/1.1 is used for proxying, which is necessary for WebSockets.
  2. proxy_set_header Upgrade $http_upgrade; and proxy_set_header Connection "upgrade";:
  • These headers are critical for upgrading an HTTP connection to a WebSocket. When the client sends a request with an Upgrade: websocket header, Nginx will recognize this and keep the connection open and persistent.
  • $http_upgrade and "upgrade" ensure that if the Upgrade header is received, Nginx forwards this header and changes the connection type appropriately.

The key to resolving this was correctly configuring Nginx to handle WebSocket upgrades. Hereā€™s what needed to be done:

IMPORTANT
Add the map Directive: This is necessary to handle the Upgrade and Connection headers correctly for WebSocket connections. This directive should be added in the http context of your Nginx configuration. This file is found at /etc/nginx/nginx.conf

http {
    map $http_upgrade $connection_upgrade {
        default upgrade;
        '' close;
    }
}

Validate and Reload Nginx: After updating your configuration, validate it with nginx -t and then reload it using sudo systemctl reload nginx.

1 Like