Coder Social home page Coder Social logo

cyralinc / approzium Goto Github PK

View Code? Open in Web Editor NEW
56.0 56.0 7.0 13.4 MB

Approzium allows a cloud service to authenticate to a database without ever having access to its password

Home Page: https://approzium.com

License: Apache License 2.0

Dockerfile 1.14% Makefile 2.24% Go 56.89% Python 34.43% Shell 3.28% Batchfile 0.38% HCL 1.65%
authentication databases hacktoberfest observability security

approzium's People

Contributors

dependabot[bot] avatar jrich523 avatar kirklandnuts avatar lorenaleao avatar timoguin avatar tyrannosaurus-becks avatar upgado avatar victorgfm avatar vrjuliao avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

approzium's Issues

Security testing

Do a general security review of the plugin, focusing on logic. Provide tests to ensure security issues don't arise over time.

Test library on Mac

Make sure we support Mac in general and especially with psycopg2 connections

Allow config to be provided via file

Currently, we allow the Authenticator's configuration to be provided by env variables. However, we will soon have accumulated over 10 environment variables that may be set before startup. It would be a nicer developer experience to also support providing them via a file, and taking the path to the config file as a parameter when starting the Approzium Authenticataor.

They would run the Go authenticator binary like this: $ authenticator -config=/path/to/config.yml. At a minimum, we would support the config file as .yml (because it supports comments, which can be very useful for people to use in explaining why this or that is set), but it would be a bonus if json were supported too.

Test support for AWS EC2 instances

  • Determine if our SDK currently supports automatically detecting their identity directly and/or through roles that aren't explicitly set
  • If it doesn't, add support

Fuzz the Go authenticator

This is intended to prevent an attacker from getting us to panic in order to maliciously take us down.

Add tests for non-E2E Python tests on different versions

We make the claim that we support Python 3.5+, however, it would be good to verify that in our CI. We can add matrix tests that run tests on Python 3.5, 3.6, 3.7, 3.8. Those tests have to run quickly, so they cannot include the Docker environment. Thus, we will have to mock the authenticator functionality in Python to allow the tests to run. This is not bad in itself because it allows us to isolate testing the Python SDK from the authenticator

document approzium

  • add explanatory comments throughout code
  • document usage
  • explain concept, architecture
  • getting started

Improve CI

Intended changes:

  • I found out that one of the automatic Python linting tools was being run under "check" mode instead of the "fix it for me" mode.
  • Right now, all tests are ran under one "test" job/step. Ideally, we split that up into more descriptive and smaller units. Such as: "Authenticator Go tests", "Simple Python connection+connection pool tests", and then "Psycopg2 Test suite".
  • Implement/test things that would happen on each release. These include: publish Authenticator image to Docker, generate Go binary, publish Pip package. One little challenge that I anticipate here is being able to test this without spamming the releases section of the repo.

Test support for AWS Lambda

  • Determine if our SDK currently supports automatically detecting their identity directly and/or through roles that aren't explicitly set
  • If it doesn't, add support

Add Authenticator endpoint for adding credentials

I'm thinking we could add an endpoint in the Authenticator for adding credentials that would be accessible to clients. Since Authenticator needs them in a certain format, Authenticator would do the work of adding them in the format it needs.

This needs further design, but the endpoint would be one that you'd need admin access to. So we'd need to figure out a way to determine who administrators should be and how they authenticate to this Authenticator endpoint.

Then, after authenticating as an administrator, someone could CRUD credentials for clients. They would post to some endpoint, where the path would be something like the object the caller will be able to access (maybe a postgres DB, but also could be mysql, etc.). And the body would be something like:

{
  "access_granted_to": [
    {
      // Each object here would vary by platform. For AWS it would be their IAM arns, but this should be extensible for Azure and GCP too.
    }
  ],
  "credentials": [
    {
      // Each object here would vary too due to needing to support multiple types of databases, but the reason we should allow multiple is because maybe somebody would want to be able to add 3 sets of credentials in case they're shared and they don't want to run out.
    }
  ],
}

After receiving such a request, we would turn around and store the creds in whatever credential storage mechanism they're using.

I'm not totally stuck on this design, just trying to provide some food for thought. Also, I think this should be prioritized as low because, since users can also directly add credentials to things, this is more of a "nice to have" for UX than a "must have".

Add server-side logging for attribution

We should log inbound and outbound calls, as well as information that can help with attributing calls to a particular identity. However, by default, sensitive values should be redacted. There should be a toggle to make them not redacted that is via an API call that can only be changed by an administrator.

Implement authenticator client with local state

from approzium import Authenticator
from approzium.psycopg2 import connect

auth = Authenticator(authenticator_addr, optional_iam_arn)
connect(<typical psycopg.connect() args>, authenticator = auth)

or

from approzium import Authenticator, set_default_authenticator
from approzium.psycopg2 import connect

auth = Authenticator(authenticator_addr, optional_iam_arn)
set_default_authenticator(auth)
connect(<typical psycopg.connect() args>)

or

from approzium import Authenticator, set_default_authenticator
import approzium.psycopg2

auth = Authenticator(authenticator_addr, optional_iam_arn)
set_default_authenticator(auth)
approzium.psycopg2.connect(<typical psycopg.connect() args>)

Be able to create sync connections

When psycopg2 connect() is called with async=true, we expect that it returns an async conneciton for which the query behavior would be different. With this type of connection, the user would have to call wait() to get the results from a query, rather than having the execute() call block until results are returned. source

We want to be able to call connect() with async=true because it allows us to poll the connection without leaving the approzium python sdk, but above that we want no change to the query behavior. If we cannot revert the async connection to a sync connection, then we have to find an alternative method of establishing the connection.

Implement scram-sha-256 for pw encryption

Postgres 10.0 and beyond include scram-sha-256 encryption for pw auth, which is more secure than md5

we might have to look into new client libs because per the docs:

it is not supported by older client libraries

If possible, please implement support for scram-sha-256 encryption as an alternative to md5

Implement CI

  • run Psycopg2 test suite using our connections.
  • run our own tests
  • style check / lint
  • if tag, publish to PyPi, Dockerhub.

RFC: API Design

Request For Comment

This Github issue is a Request For Comment regarding adding an administrative API to Approzium.

Background

Currently, to plant credentials for the Go authenticator to use in creating connections, people must directly place credentials in their storage back-end. They are placed as a JSON map, for example, these are placed for those using HashiCorp Vault:

$ vault write approzium/1.2.3.4:5432 [email protected]
# creds.json is: 
{
    "password": "asdfghjkl",
    "iam_arns": [
        "arn:aws:iam::accountid:role/rolename1",
        "arn:aws:iam::accountid:role/rolename2"
    ]
}

This approach is brittle. A slight typo on the user's end regarding the Vault path or the credentials will result in the Authenticator failing to locate or authorize use of the credentials.

We would like to add an API that improves user experience.

Proposal

At Startup

We will take a secure by default approach, since this is a security application.

  • We would fail if a credential manager wasn't configured for persistent storage.
  • If we didn't detect any administrators, we would provide a message like, "Welcome! Your username is admin, and your password is sdfhawieuninf (random high-entropy string every time)! We encourage you to create a new user under your real name and to delete this one when done".
  • Using this username and password, the admin could set up more administrators.
  • Usernames and passwords would be provided in every API request through basic auth.
  • Each admin would only be able to view and update their own password; they would be able to add and delete other admins at will. This is a naive trust model, but is intended for first-iteration design. Designing and implementing a policy system is out of scope for the original design.

Admin Management Endpoints

We would expose the following endpoints:

  • POST (create, update, delete) /v1/administrators/:username
    • password
  • GET (list response) /v1/administrators
    • // all the people

Credential Management Endpoints

We would expose endpoints specific to each database type for which we were given credentials. For example, since we currently support postgres:

  • POST (create, update, delete) /v1/creds/:human-friendly-name
    • dbhost: 127.0.0.1
    • dbport: 1234
    • username: bob
    • password: foo
    • grant_access_to: { iam_arns: [foo] }
  • GET (list response) /v1/creds

Endpoint Visibility

We would ensure that all endpoints were well described from the outset using Swagger, so that it would be easy in the future for others to build integrations with us, or for a UI to be built.

Comments/Thoughts Welcome!

This is an early-stage RFC and I am happy to edit it as your feedback arrives! Please don't hesitate to comment. :-)

Support HA

Right now, Approzium is stateless. So, HA can be achieved by simply having 3 instances of the Authenticator up and if one fails, the other 2 are still there.

We should document prescriptive best practices for this in an AWS EC2 environment. How big should the EC2 instances be? Should they be behind a load balancer? This will probably need to tie into the Terraform config that's given in #19 .

We also need to document inside the Authenticator's code that caching is not desirable. The reason is, if we were to receive a write (someday) and cache it, the other two instances that didn't service the write might have different data cached. We should document for developers that the Authenticator's HA design is stateless.

Support server-side tracing

This ticket is to support tracing using OpenTracing. In the Go authenticator, we should implement receiving tracing info, creating a span for the time a request is in Approzium, and sending trace metrics to the properly configured location.

Investigate better SSL library compatibility

  • Currently, we load whatever ssl library is on the system. However, there is no guarantee that this is the same SSL library that libpq is using. Ideally, we can use ensure that the SSL library we are using is the same one libpq is using.

run E2E test in aws lambda

we want to bring up an app using approzium sdk to connect to a database without passing a password

  • the password should be stored in vault against the ARN of the IAM assigned to the lambda

something we're looking for here is that the sts identity stuff works out of the box with aws resources

possible challenges

  • py dependencies on aws lambda
  • communication sdk <> authenticator

Implement Swagger

Adding metrics will add our first endpoint that is not gRPC. We should implement Swagger for both our gRPC and non-gRPC endpoints to make it easy for folks to use us even if we don't yet have an SDK in their language.

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.