Password Authentication Setup on Local

    Authentication and authorization are two main pillars for data security. While a Presto cluster can be set up to run without authentication for development purposes, production clusters must be secured at all times. Setting up secure clusters comes with its own challenges in terms of the involved setup and configuration changes. In this blog, we try to set up a secure Presto cluster on a local machine using password file based authentication and resolve the errors incrementally that come along the way.

    Troubleshooting SSL handshake related errors can be overwhelming: most of the errors are not obvious, and Google searches can frequently give unsatisfactory answers. Before dealing with these errors, it is recommended to have good knowledge of

    1. What happens in a typical SSL handshake?
    2. How are TLS connections different from mTLS connections?
    3. What is a keystore and a truststore?
    4. What is the role of keystore and truststore in SSL connections?
    5. Basic Java tools like keytool for managing keystores, truststores and certificates.

    Expectations

    1. Configure a Presto cluster to authenticate users with password file based authentication on a local machine.
    2. Verify that once the Presto cluster is secured, no user is able to connect to the server without authenticating themselves.

    SSL Handshakes

    Let us start with some theory that I feel is important to understand before going to hands on. SSL handshakes are a mechanism by which client and server establish the trust and logistics required to secure their connection over the network. SSL handshake involves many steps, but we go over only the ones relevant for this blog:

    • Client provides a list of possible SSL versions and cipher suites to use.
    • Server agrees on a particular SSL version and cipher suite, responding with its certificate from its keystore.
    • Client verifies the authenticity of this certificate by checking it against a list of trusted Certificate Authorities (CAs) using its truststore.

    Keystore and Truststore

    Keystore and Truststore are used to manage the keys and certificates required for secure communication.

    • The Keystore stores your private keys and the corresponding public certificates. During a SSL handshake, the Presto server uses its keystore to present its identity to the client such as Presto CLI.
    • A truststore stores only public certificates, typically from trusted Certificate Authorities. Clients such as Presto CLI will make use of its truststore to verify the certificate presented by the Presto coordinator. If the server’s certificate or the corresponding CA is not in the client’s truststore, the connection fails with SSLHandshakeException.

    It is important to note that Java provides default truststore (cacerts) but there is no default keystore. So during a handshake, the connection can succeed when the server presents a certificate which is issued by well known CAs because the certificates issued by these CAs are already present in the default truststore. When testing, the certificate could be a self-signed one, and a custom truststore will be needed which contains the presented certificate.

    TLS and mTLS

    mTLS stands for mutual TLS (Transport Layer Security). The key difference between TLS and mTLS is that TLS uses a one way handshake where only the server presents its certificate to the client and the client verifies that certificate using its truststore. However, mTLS adds a mandatory second step where the client also presents its certificate to the server, allowing the server to authenticate the client, ensuring a strict two-way, zero trust security. In a TLS handshake, the client only needs a truststore to verify the server’s identity, while in a mTLS handshake, both server and client need a keystore and truststore to present the certificate and verify the other’s identity.

    Can keystore and truststore be the same?

    Because both a keystore and truststore are needed in an mTLS handshake for both the involved parties, this raises the obvious question – Do keystore and truststore need to be different? Can they use the same file?

    Technically, a keystore and truststore can use the same physical file as they both use the same underlying formats and management tools like the Java Keytool. However, it is recommended to keep them separate due to the following reasons:

    • Security Risk: Truststore often have lower security requirements since they only contain public data. If you combine them, anyone with access to truststore can access your highly sensitive private keys as well.
    • Maintenance: Keeping keystore and truststore separate makes it easier to manage the certificates especially when certificates are rotated at regular intervals.
    • Default Values: Java provides a default truststore, but there is no default keystore.

    Keytool

    The Keytool command is a key and certificate management utility provided by Java as part of its releases. Please refer to the official documentation and Introduction to Keytool for more information.

    Set up Presto on a local machine

    Use Intellij IDEA for setting up Presto on local. See Building Presto for instructions.

    Set up password file based authentication

    Having almost no idea about how SSL connection works internally, I performed these steps:

    1. Created a password.db file for configuring test user using the commands:
    pratyakshsharma@Pratyakshs-MacBook-Pro Documents % vi password.db 
    pratyakshsharma@Pratyakshs-MacBook-Pro Documents % htpasswd -B -C 10 password.db test
    New password:
    Re-type new password:
    Adding password for user test

    I was not sure if a keystore path was needed for the Presto coordinator, so I added only these configurations to config.properties:

    http-server.https.enabled=true
    http-server.https.port=8443
    http-server.authentication.type=PASSWORD

    I created a new password-authenticator.properties file:

    password-authenticator.name=file
    file.password-file=/Users/pratyakshsharma/Documents/password.db

    When I tried to start the Presto server, this error appeared:

    1) [Guice/ErrorInCustomProvider]: NullPointerException
      while locating HttpServerProvider
      at HttpServerModule.configure(HttpServerModule.java:54)
      while locating HttpServer
    
    Learn more:
      https://github.com/google/guice/wiki/ERROR_IN_CUSTOM_PROVIDER
    Caused by: NullPointerException
    	at java.base/Objects.requireNonNull(Objects.java:208)
    	at java.base/UnixFileSystem.getPath(UnixFileSystem.java:263)
    	at java.base/Path.of(Path.java:147)
    	at HttpServer.tryLoadPemKeyStore(HttpServer.java:526)
    	at HttpServer.<init>(HttpServer.java:238)
    	at HttpServerProvider.get(HttpServerProvider.java:145)
    	at HttpServerProvider.get(HttpServerProvider.java:43)
    	at ProviderInternalFactory.provision(ProviderInternalFactory.java:86)
    	at BoundProviderFactory.provision(BoundProviderFactory.java:72)
    	at ProviderInternalFactory$1.call(ProviderInternalFactory.java:67)
    	at ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:109)
    	at LifeCycleModule.provision(LifeCycleModule.java:53)
    	at ProvisionListenerStackCallback$Provision.provision(ProvisionListenerStackCallback.java:117)
    	at ProvisionListenerStackCallback.provision(ProvisionListenerStackCallback.java:66)
    	at ProviderInternalFactory.circularGet(ProviderInternalFactory.java:62)
    	at BoundProviderFactory.get(BoundProviderFactory.java:59)
    	at ProviderToInternalFactoryAdapter.get(ProviderToInternalFactoryAdapter.java:40)
    	at SingletonScope$1.get(SingletonScope.java:169)
    	at InternalFactoryToProviderAdapter.get(InternalFactoryToProviderAdapter.java:45)
    	at InternalInjectorCreator.loadEagerSingletons(InternalInjectorCreator.java:213)
    	at InternalInjectorCreator.injectDynamically(InternalInjectorCreator.java:186)
    	at InternalInjectorCreator.build(InternalInjectorCreator.java:113)
    	at Guice.createInjector(Guice.java:87)
    	at Bootstrap.initialize(Bootstrap.java:263)
    	at PrestoServer.run(PrestoServer.java:169)
    	at PrestoServer.main(PrestoServer.java:103)

    On checking the line of code which was throwing the NullPointerException, I figured out a keystore was needed for the http-server. So I created a keystore on the local system with the following commands:

    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % keytool -genkeypair -alias presto -keyalg RSA -keystore keystore.jks
    Enter keystore password:  
    Re-enter new password: 
    What is your first and last name?
      [Unknown]:  pratyaksh sharma
    What is the name of your organizational unit?
      [Unknown]:  
    What is the name of your organization?
      [Unknown]:  
    What is the name of your City or Locality?
      [Unknown]:  
    What is the name of your State or Province?
      [Unknown]:  
    What is the two-letter country code for this unit?
      [Unknown]:  
    Is CN=pratyaksh sharma, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
      [no]:  yes
    
    Enter key password for <presto>
    	(RETURN if same as keystore password):  
    
    Warning:
    The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore.jks -destkeystore keystore.jks -deststoretype pkcs12".

    Then I added two new properties in config.properties:

    http-server.https.keystore.path=/Users/pratyakshsharma/Documents/presto-https/keystore.jks
    http-server.https.keystore.key=password

    Then I tried again to start the Presto server, and the following error was displayed:

    2026-04-14T14:33:18.767+0545	INFO	main	com.facebook.presto.server.security.PasswordAuthenticatorManager	-- Loading password authenticator --
    2026-04-14T14:33:18.767+0545	ERROR	main	com.facebook.presto.server.PrestoServer	Password authenticator file is not registered
    java.lang.IllegalStateException: Password authenticator file is not registered
    	at com.google.common.base.Preconditions.checkState(Preconditions.java:601)
    	at com.facebook.presto.server.security.PasswordAuthenticatorManager.loadPasswordAuthenticator(PasswordAuthenticatorManager.java:73)
    	at com.facebook.presto.server.PrestoServer.run(PrestoServer.java:209)
    	at com.facebook.presto.server.PrestoServer.main(PrestoServer.java:103)

    This is because PasswordAuthenticatorPlugin is not registered with the server. To fix this, I added this line to plugin.bundles in config.properties:

    ../presto-password-authenticators/pom.xml

    When I tried again, the server started successfully.

    2026-04-16T12:14:39.909+0545	INFO	main	com.facebook.presto.server.PrestoServer	======== SERVER STARTED ========

    Next I tried to run Presto CLI and the following error appeared:

    pratyakshsharma@Pratyakshs-MacBook-Pro presto % presto-cli/target/presto-cli-0.297-SNAPSHOT-executable.jar --user test --password
    Password:
            Exception in thread "main" java.lang.IllegalArgumentException: Authentication using username/password requires HTTPS to be enabled
            at com.google.common.base.Preconditions.checkArgument(Preconditions.java:143)
            at com.facebook.presto.cli.QueryRunner.setupBasicAuth(QueryRunner.java:166)
            at com.facebook.presto.cli.QueryRunner.<init>(QueryRunner.java:95)
            at com.facebook.presto.cli.Console.run(Console.java:143)
            at com.facebook.presto.cli.Presto.main(Presto.java:31)

    To enable HTTPS as the error suggested, I had to include the --server flag with an HTTPS endpoint because it uses http://localhost:8080 by default.

    I ran the new command –

    pratyakshsharma@Pratyakshs-MacBook-Pro presto % presto-cli/target/presto-cli-0.297-SNAPSHOT-executable.jar --user test --server https://localhost:8443 --password
    Password: 
    presto> 

    And that was successful!

    I was able to access the interactive shell, but when I tried to run a simple query such as show catalogs, I hit another error:

    presto> show catalogs;
    Error running command: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    For authentication related errors, you will not see any stacktrace on the Presto console because the query does not reach the Presto coordinator.

    On exploring a bit, I figured out that the Common Name that I had used in my certificate in keystore was not correct and it needs to be the unqualified hostname of the Presto coordinator. So I created a fresh keystore as below:

    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % hostname
    Pratyakshs-MacBook-Pro.local
    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % keytool -genkeypair -alias presto -keyalg RSA -keystore keystore1.jks 
    Enter keystore password:  
    Re-enter new password: 
    What is your first and last name?
      [Unknown]:  Pratyakshs-MacBook-Pro.local
    What is the name of your organizational unit?
      [Unknown]:  
    What is the name of your organization?
      [Unknown]:  
    What is the name of your City or Locality?
      [Unknown]:  
    What is the name of your State or Province?
      [Unknown]:  
    What is the two-letter country code for this unit?
      [Unknown]:  
    Is CN=Pratyakshs-MacBook-Pro.local, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
      [no]:  yes
    
    Enter key password for <presto>
    	(RETURN if same as keystore password):  
    
    Warning:
    The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore1.jks -destkeystore keystore1.jks -deststoretype pkcs12".

    I updated the value of the property in config.properties:

    http-server.https.keystore.path=/Users/pratyakshsharma/Documents/presto-https/keystore1.jks

    and restarted the server.

    On trying the query on Presto CLI again, the same error appeared as before:

    presto> show catalogs;
    Error running command: javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

    This error was super confusing and gave no direct idea of what might have gone wrong. At this point I almost gave up, and I created an issue on Presto GitHub.

    While waiting for suggestions on the raised ticket, I started reading further about the Java Truststore File for TLS in the Presto documentation, and I found out that For the Presto CLI to trust the Presto coordinator, the coordinator’s certificate must be imported to the CLI’s truststore.

    I followed the documentation in Importing self-signed certificates from a Presto (Java) server to a Java Truststore to import the server’s certificate to the CLI’s truststore.

    While the Presto server was running, I ran these commands:

    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % echo QUIT | openssl s_client -showcerts -connect localhost:8443 | awk '/-----BEGIN CERTIFICATE-----/ {p=1}; p; /-----END CERTIFICATE-----/ {p=0}' > presto.cert
    Connecting to ::1
    Can't use SSL_get_servername
    depth=0 C=Unknown, ST=Unknown, L=Unknown, O=Unknown, OU=Unknown, CN=Pratyakshs-MacBook-Pro.local
    verify error:num=18:self-signed certificate
    verify return:1
    depth=0 C=Unknown, ST=Unknown, L=Unknown, O=Unknown, OU=Unknown, CN=Pratyakshs-MacBook-Pro.local
    verify return:1
    DONE
    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % keytool -import -alias presto-cert -file ./presto.cert -keystore ./presto-truststore.jks
    Enter keystore password:  
    Re-enter new password: 
    Owner: CN=Pratyakshs-MacBook-Pro.local, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
    Issuer: CN=Pratyakshs-MacBook-Pro.local, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
    Serial number: cfbc633
    Valid from: Wed Apr 01 21:19:34 IST 2026 until: Tue Jun 30 21:19:34 IST 2026
    Certificate fingerprints:
    	 SHA1: D8:C6:0D:DB:15:FC:EA:0E:C4:03:B3:B7:5F:3A:AB:42:A5:2A:A5:D3
    	 SHA256: DA:AD:9F:03:6A:A1:6E:8B:FC:0C:EC:C1:C8:5E:23:07:8D:06:38:D7:48:75:F3:7F:92:D9:86:46:72:33:5D:AA
    Signature algorithm name: SHA256withRSA
    Subject Public Key Algorithm: 2048-bit RSA key
    Version: 3
    
    Extensions: 
    
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
    KeyIdentifier [
    0000: 1B 94 02 F7 C4 0B 85 AC   55 DE 9E 5C E2 00 43 0A  ........U..\..C.
    0010: 3B ED A6 29                                        ;..)
    ]
    ]
    
    Trust this certificate? [no]:  yes
    Certificate was added to keystore

    Next I started the Presto CLI and included the truststore related flags:

    pratyakshsharma@Pratyakshs-MacBook-Pro presto % presto-cli/target/presto-cli-0.297-SNAPSHOT-executable.jar --server https://localhost:8443 --truststore-path /Users/pratyakshsharma/Documents/presto-https/presto-truststore.jks --truststore-password password --user test --password
    Password:
    presto>

    However, on running show catalogs, I hit another error:

    presto> show catalogs;
    Error running command: javax.net.ssl.SSLPeerUnverifiedException: Hostname localhost not verified:
        certificate: sha256/7HpqT7WDjK7UF+pwa/snkEhUEXWp8WmmJwPp7nWnhyc=
        DN: CN=Pratyakshs-MacBook-Pro.local, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
        subjectAltNames: []
    presto> 
    presto>

    This error was more obvious than the previously encountered ones: the certificate included in the truststore had to have localhost as the CN.

    I repeated the steps already performed earlier, but using localhost as the CN this time.

    1. Generate self-signed certificate for Presto coordinator
    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % keytool -genkeypair -alias presto -keyalg RSA -keystore keystore_localhost.jks
    Enter keystore password:  
    Re-enter new password: 
    What is your first and last name?
      [Unknown]:  localhost
    What is the name of your organizational unit?
      [Unknown]:  
    What is the name of your organization?
      [Unknown]:  
    What is the name of your City or Locality?
      [Unknown]:  
    What is the name of your State or Province?
      [Unknown]:  
    What is the two-letter country code for this unit?
      [Unknown]:  
    Is CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown correct?
      [no]:  yes
    
    Enter key password for <presto>
    	(RETURN if same as keystore password):  
    
    Warning:
    The JKS keystore uses a proprietary format. It is recommended to migrate to PKCS12 which is an industry standard format using "keytool -importkeystore -srckeystore keystore_localhost.jks -destkeystore keystore_localhost.jks -deststoretype pkcs12".
    1. Update the property in config.properties:
    http-server.https.keystore.path=/Users/pratyakshsharma/Documents/presto-https/keystore_localhost.jks

    and restarted the server.

    1. Import the keystore certificate to the CLI’s truststore using the following commands:
    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % echo QUIT | openssl s_client -showcerts -connect localhost:8443 | awk '/-----BEGIN CERTIFICATE-----/ {p=1}; p; /-----END CERTIFICATE-----/ {p=0}' > presto1.cert
    Connecting to ::1
    Can't use SSL_get_servername
    depth=0 C=Unknown, ST=Unknown, L=Unknown, O=Unknown, OU=Unknown, CN=localhost
    verify error:num=18:self-signed certificate
    verify return:1
    depth=0 C=Unknown, ST=Unknown, L=Unknown, O=Unknown, OU=Unknown, CN=localhost
    verify return:1
    DONE
    pratyakshsharma@Pratyakshs-MacBook-Pro presto-https % keytool -import -alias presto-cert -file ./presto1.cert -keystore ./presto1-truststore.jks
    Enter keystore password:  
    Re-enter new password: 
    Owner: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
    Issuer: CN=localhost, OU=Unknown, O=Unknown, L=Unknown, ST=Unknown, C=Unknown
    Serial number: 3aff7a41
    Valid from: Wed Apr 01 23:37:53 IST 2026 until: Tue Jun 30 23:37:53 IST 2026
    Certificate fingerprints:
    	 SHA1: 77:C6:D5:EE:49:44:BE:2F:D8:B8:5C:A4:7A:5B:91:54:7A:08:73:97
    	 SHA256: 9D:89:93:EB:E9:C7:6E:98:37:27:F0:1B:54:41:38:C1:AB:66:63:59:61:D2:3B:26:E4:49:92:13:75:53:8C:4F
    Signature algorithm name: SHA256withRSA
    Subject Public Key Algorithm: 2048-bit RSA key
    Version: 3
    
    Extensions: 
    
    #1: ObjectId: 2.5.29.14 Criticality=false
    SubjectKeyIdentifier [
    KeyIdentifier [
    0000: 93 07 D0 04 B7 02 73 B9   E0 9B F7 8F 06 0A C4 85  ......s.........
    0010: A7 43 20 A2                                        .C .
    ]
    ]
    
    Trust this certificate? [no]:  yes
    Certificate was added to keystore
    1. Restart the Presto CLI and run show catalogs query, everything worked like a charm:
    pratyakshsharma@Pratyakshs-MacBook-Pro presto % presto-cli/target/presto-cli-0.297-SNAPSHOT-executable.jar --server https://localhost:8443 --truststore-path /Users/pratyakshsharma/Documents/presto-https/presto1-truststore.jks --truststore-password password --user test --password
    Password: 
    presto> show catalogs;
       Catalog   
    -------------
     blackhole   
     delta       
     druid       
     example     
     hana        
     hive        
     hudi        
     iceberg     
     jmx         
     localfile   
     memory      
     mysql       
     pinot       
     postgresql  
     prometheus  
     singlestore 
     sqlserver   
    
    Query 20260401_181326_00000_3qt9p, FINISHED, 1 node
    Splits: 19 total, 19 done (100.00%)
    [Latency: client-side: 0:03, server-side: 0:02] [0 rows, 0B] [0 rows/s, 0B/s]
    
    presto> exit;

    To verify that any user cannot access my cluster without authentication, I tried the Presto CLI command without providing --user and --password flags. As expected, it did not allow me to run any query.

    pratyakshsharma@Pratyakshs-MacBook-Pro presto % presto-cli/target/presto-cli-0.297-SNAPSHOT-executable.jar --server https://localhost:8443 --truststore-path /Users/pratyakshsharma/Documents/presto-https/presto1-truststore.jks --truststore-password password                      
    presto> show catalogs;
    Error running command: Authentication failed: Unauthorized
    presto> exit

    Upon reading further, I found this super useful link about SSL Handshake Failures that talks about the different errors which are encountered when setting up SSL connections. I encourage everyone to give it a read.

    Follow Us