GithubHelp home page GithubHelp logo

chandranarreddy / gopqr Goto Github PK

View Code? Open in Web Editor NEW
2.0 2.0 0.0 23 KB

Golang handler for managing zero-touch rotating PostGres Credentials.

License: MIT License

Go 100.00%
zerotouch rotating-credentials libpq postgresql hitless

gopqr's Introduction

gopqr

Go

Golang handler for zero-touch rotating credentials Postgres Connections. Use this wrapper for lib/pq driver to facilitate zero-touch rotating credentials connections for your applications.

Zero Touch Credentials Rotation

How many times have we wished that credentials were refreshed without needing to take a hit on your application servers. This quick and simple utility gopqr solves the problem if you have a Golang based application connecting using lib/pq to a Postgres database.

How does it work?

gopqr driver works by alternating between odd and even pairs of credentials for each subsequent database connection it makes. So, when credentials to one of the odd/even accounts changes, the driver would encounter 'Credential failure' code when attempting to make a connection using already expired credentials of this account. This is when the driver falls back to the still-good account to continue making the database connection and asynchronously invokes the 'CredentialRefresher' function t o refresh the credentials set, thereby avoiding a down-time. The 'CredentialRefresher' function is defined by the consumer of gopqr(you), when invoked it should fetch the latest set of credentials from storage such as a vault and reset the odd and even credentials in the driver. Make sure you do this within the protection of the inbuilt Mutex to avoid race conditions.

Okay, how do I make it happen?

Please refer to the sample code in the examples directory for usage of the driver by refreshing credentials stored in AWS Secrets Manager.

Instructions

  • If you have defined your postgres database service accounts to refresh every often, you can use this little utility to automatically refresh these credentials for you. Only requirement is that you need to have 2 such service accounts with similar privilege level for the sake of continuity while the other one is under rotation. Once you have created the second account, you are good to go!

  • Here is how you would create the driver -

  pqr := &gopqr.Driver{
      OddUsername:      s.OddUsername,
      OddPassword:      s.OddPassword,
      EvenUsername:     s.EvenUsername,
      EvenPassword:     s.EvenPassword,
      ActiveCredential: s.ActiveCredential,
    }
  • You will need to define a function that fetches the latest set of credentials from where they are stored such as from a vault or AWS Secrets Manager. This function is invoked by the driver upon encountering 'incorrect credentials' error when negotiating a new connection to the database.
  pqr.CredentialRefresher = func(pqrDriver *gopqr.Driver) {
    ..
    fetch the new credentials
    ...
    pqrDriver.AcquireLock()
    pqrDriver.OddUsername = `odd credential username fetched above`
    pqrDriver.OddPassword = `odd credential password fetched above`
    pqrDriver.EvenUsername = `even credential username fetched above`
    pqrDriver.EvenPassword = `even credential password fetched above`
    pqrDriver.ActiveCredential = `odd/even`
    pqrDriver.ReleaseLock()
    return
  }
  • Now register the newly minted driver like this -
  sql.Register("postgresrotating", pqrDriver)
  • Create the database dsn sans the credentials like this -
  dsn := fmt.Sprintf("postgres://%v/%v?sslmode=%v", MyDBAddr, MyDBName, 'require')
  • Now, open the connection to the DB using the SQL implementation of your choice -
  db, err := sqlx.Open("postgresrotating", dsn)
  • You can use the SetConnMaxLifetime parameter to set when the connections timeout, this setting defines how frequently the database connections are alternated between the odd and the even credential.
  db.SetConnMaxLifetime(time.Hour * MaxLifetimeInHours)
  • When you rotate credentials for these accounts, remember to space them apart in time (greater than one multiple of SetConnMaxLifetime value above) so the driver does not end up with credentials invalid for both accounts when it attempts to make a connection to the database at the end of a lifetime window.

  • You can get creative with the CredentialRefresher function to introduce alerting capabilities in case the function fails to accurately refresh the credentials.

Contributions

Please feel free to send a PR or raise an issue.

Author

Chandrakanth Narreddy

License

MIT License

gopqr's People

Contributors

chandranarreddy avatar

Stargazers

 avatar  avatar

Watchers

 avatar  avatar

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.