Skip to content

Latest commit

 

History

History
150 lines (89 loc) · 8.6 KB

harness_security.md

File metadata and controls

150 lines (89 loc) · 8.6 KB

Security

Harness optionally uses TLS (formerly called SSL) and OAuth2 "bearer token" Server to Server Authentication and Authorization to secure both ends of the REST API. Through TLS the client can trust the server and through OAuth2 the Harness server can authenticate and check for authorization of the client.

TLS Support

Uses http-akka server and client TLS support.

Authentication

We use "secrets" to authenticate and authorize users. This requires offline exchange of credentials but is secure when combined with TLS/SSL. The User is issued a generated token that grants them access to one or more Engine Instances managed by a Harness Server. Presenting a valid token Authenticates the User.

Authorization

If an authenticated User has been granted access Permission for resource, then the request will be processed, otherwise it will be refused with an error code. A single token acts as a key for any number of resources. For example an Admin token grants world access to all Harness resources and is used by the Harness CLI when optional Auth is enabled.

OAuth2

We use an OAuth2 user and secret for Auth. The user-id and secret are generated by Harness from the CLI using the Auth-server as a microservice. An admin user request a new user be created with certain permissions, this then get a user-id and secret from the Auth-Server and these are reported in the Harness REST API and CLI to the admin. This allows separation of Engines in a multi-tenant manner with some Engines accessible to some Users and other Engines inaccessible to protect one User's data from another User accessing it.

Some of this data flow is done by humans (the offline part) and some by the SDK to Harness communication (the online part).

Here is the OAuth2 Access Token Protocol mapped onto Harness, the microservice Auth-Server, and the humans involved.

Users and Roles

There are 2 role types. In typical use the client user-id and secret are used by the SDK on client machines and the admin user-id is used where the CLI is run. Clients have permission to send Events and Queries to specific Engines. Admins have access to all resources. You must be an admin to use most of harness-cli.

The see the REST API used to implement User management see the later portion if the REST Spec

For the CLI that manages users see the Commands Spec

Creating Users and Enabling Auth

The typical configuration of Harness is with the Harness and Auth Servers running on the same machine with the CLI installed. Although these can all run on different machines we describe the simple case below.

To create Users the CLI is used and so this is run on the Harness Server. A client type user is created for every Engine but only an admin user can do this since any admin user is like a superuser with complete access permissions to any system resource.

  • client: is used to access engines by sending and events and queries. This is the user role typically used by the Java SDK. The Python SDK can use this too for events and queries
  • admin: this user role allows superuser type access to all of the REST API and so is only granted to administrators, especially a user of the CLI. Some commands will fail unless the CLI user is an admin.

Client users can access only the engine-id they have access to. In this way a multi-tenant setup of Harness will protect one Engine from access by other users. All users (except the admins) are blocked from all Engines unless expressly granted permission when the user-id is created or a later grant of permission is made.

Setup Security

The default Harness install runs out of the box but is without any security, which may be fine for your deployment. Many will choose to put Harness behind a firewall so that no connections can be made except for the app-server using Harness. In this case no-Auth and HTTP may be fine.

If you need to connect over the internet to Harness you will need the Authentication/Authorization Server (Auth-server for short) and TLS/SSL:

  • TLS/SSL encrypts all traffic and allows the client to trust the Harness connection
  • Authentication allows Harness to recognize the User by the Secret token presented.
  • Authorization protects all resources from access by a User without permission.

Together these provide all that is needed for secure communication even in insecure networks like the internet.

TLS/SSL

Harness needs a certificate, like any HTTP/HTTPS server. The Harness SDKs and CLI need to have a trust chain or a self-signed certificate to de-crypt and therefore trust that they are connecting to the instance of Harness they expect.

  • Harness these are in harness-env but may be overridden in the host env or docker-comose.yml:

    export REST_SERVER_HOST=${REST_SERVER_HOST:-localhost}
    export HARNESS_SSL_ENABLED=${HARNESS_SSL_ENABLED:-false}
    export HARNESS_KEYSTORE_PASSWORD=${HARNESS_KEYSTORE_PASSWORD:-changeit}
    export HARNESS_KEYSTORE_PATH=${HARNESS_KEYSTORE_PATH:-$HARNESS_HOME/conf/harness.jks}
    

    To apply changes:

    harness stop
    harness start
    

    Harness is now using HTTPS. The certificate should be tied to the REST_SERVER_HOST address or the external address that routed to Harness so it will change from localhost. For instance if Harness is using REST_SERVER_HOST=0.0.0.0 the external address will be a DNS name or fixed IP address.

    For instructions to create a .jks, which is a special format for the JVM certificates, see instructions here The provided default harness.jks will work for localhost

  • Harness-cli these are in harness-cli-env but may be overridden in the host env or docker-comose.yml (if you are using one):

    export HARNESS_SERVER_ADDRESS=${HARNESS_SERVER_ADDRESS:-localhost}
    export HARNESS_CLI_SSL_ENABLED${HARNESS_CLI_SSL_ENABLED:-false}
    export HARNESS_CLI_CERT_PATH=${HARNESS_CLI_CERT_PATH:-$HARNESS_CLI_HOME/harness.pem}
    

In order to communicate with Harness using TLS, the CLI uses the Python SDK and this will need the above config.

Authentication/Authorization (Auth)

Auth starts by creating users see Commands for User and Role Management. At minimum you must have an admin user to use the CLI. This user can also be used to send test events but typically you will create client users for sending input and queries.

Create a User

In order to do anything with Users, or Permissions you must start the harness authentication micro-service (this should be running already of using docker-compose).

harness-cli start # already running in docker-compose

With all services running and the cli functioning properly (try harness-cli status) creates a User with an admin Role.

harness-cli user-add admin

This will report back a user-id and secret, make note of them. To use the default setup in bin/harness-env copy the secret to a file, here named with the user-id:

echo <user-secret> > path/to/secret/file

When the admin user is created a hash of the secret is stored in the Auth-Server DB so the secret is never stored on the server and no reference needs to be made to it.

At this point the Admin User is created and exists in the Auth-server's DB. But Auth is not enabled for Harness or the Harness-cli.

Configure

  • Harness: turn on auth, by setting the following in harness-env or the in the host env (or wherever docker-compose requires)

    export HARNESS_AUTH_ENABLED=true
    

    You may now restart Harness and it will enforce Auth.

  • Harness-cli To use any REST endpoint you will need either and Admin or Client User with access. For the CLI this means the Admin User created above must be setup

    In the env or by changing hanress-cli-env set these env variables

    export HARNESS_CLI_AUTH_ENABLED=true
    export ADMIN_USER_ID=<id-returned-from-user-add>
    export ADMIN_USER_SECRET_LOCATION=/path/to/secret/file
    
    

The CLI does not have a running process so as soon as you make these changes, the CLI will immediately start using the Admin User ID and Secret.

harness-cli status engines

This should return a list of any engines in the system.