diff --git a/libs/MST/Vault.pm b/libs/MST/Vault.pm
new file mode 100644
index 0000000000000000000000000000000000000000..cfb95f64361c82a543225f120feee07ce0a6922a
--- /dev/null
+++ b/libs/MST/Vault.pm
@@ -0,0 +1,100 @@
+# Begin-Doc
+# Name: MST::Vault
+# Type: module
+# Description: MST specific wrapper around Local::Vault
+# End-Doc
+package MST::Vault;
+require 5.000;
+use parent "Local::Vault";
+use Local::Env;
+use Local::CurrentUser;
+use Local::Vault;
+use strict;
+
+# Begin-Doc
+# Name: new
+# Type: method
+# Description: opens a new vault connection
+# Syntax: See syntax for Local::Vault with the following addition:
+#   This method will attempt to fill in a variety of defaults - trying multiple ways to get a connection
+#   to vault service based on how we use it in S&T environment.
+#
+#   Example: $vault = new MST::Vault()
+#
+# End-Doc
+sub new {
+    my ( $self, %opts ) = @_;
+    my $env = &Local_Env();
+    my $vault;
+
+    my $vault_addr = $ENV{VAULT_ADDR} || "https://vault.mst.edu";
+
+    # Get app user for k8s app role authentication
+    my $app = $ENV{APP_USER};
+
+    if ( -r "/vault/secrets/token" ) {
+        open( my $in, "</vault/secrets/token" );
+        chomp( my $token = <$in> );
+        close($in);
+
+        $vault = new Local::Vault( url => $vault_addr, token => $token );
+    }
+    elsif ( $app && -r "/run/secrets/kubernetes.io/serviceaccount/token" ) {
+        my $k8s_token;
+        open( my $in, "</run/secrets/kubernetes.io/serviceaccount/token" );
+        chomp( $k8s_token = <$in> );
+        close($in);
+
+        # No easy way to figure out what cluster we are on
+        # Maybe narrow by looking at IP range?
+        my @mounts = ();
+        if ( $ENV{VAULT_K8S_MOUNT} ) {
+            push( @mounts, $ENV{VAULT_K8S_MOUNT} );
+        }
+        else {
+            if ( !$ENV{LOCAL_ENV} || $ENV{LOCAL_ENV} =~ /dev/ ) {
+                push( @mounts, "k8s-apps-dev", "rke-apps-d" );
+            }
+            if ( !$ENV{LOCAL_ENV} || $ENV{LOCAL_ENV} =~ /test/ ) {
+                push( @mounts, "k8s-apps-dev", "rke-apps-t" );
+            }
+            if ( !$ENV{LOCAL_ENV} || $ENV{LOCAL_ENV} =~ /prod/ ) {
+                push( @mounts, "k8s-apps", "rke-apps-p" );
+            }
+        }
+        foreach my $mount (@mounts) {
+            eval {
+                $vault = new Local::Vault(
+                    url       => $vault_addr,
+                    k8s_mount => $mount,
+                    k8s_role  => "app-$app",
+                    k8s_token => $k8s_token
+                );
+            };
+            last if ($vault);
+        }
+    }
+    elsif ( -f $ENV{VAULT_SECRET_ID_FILE} && -f $ENV{VAULT_ROLE_ID_FILE} ) {
+        my $role_id;
+        open( my $in, "<", $ENV{VAULT_ROLE_ID_FILE} );
+        $role_id = <$in>;
+        close($in);
+
+        my $secret_id;
+        open( my $in, "<", $ENV{VAULT_SECRET_ID_FILE} );
+        $secret_id = <$in>;
+        close($in);
+
+        $vault = new Local::Vault( url => $vault_addr, role_id => $role_id, secret_id => $secret_id );
+    }
+
+    if ( !$vault ) {
+        $vault = new Local::Vault( url => $vault_addr, %opts );
+    }
+
+    if ( !$vault ) {
+        die "no vault login method succeeded";
+    }
+
+    return $vault;
+}