diff --git a/README.md b/README.md index 692678d3..6de16b43 100644 --- a/README.md +++ b/README.md @@ -6,11 +6,8 @@ a highly available and distributed web application. Optimizely Full Stack is A/B testing and feature flag management for product development teams. Experiment in any application. Make every feature on your roadmap an opportunity to learn. Learn more at https://www.optimizely.com/platform/full-stack/, or see the [documentation](https://docs.developers.optimizely.com/full-stack/docs). -Optimizely Rollouts is free feature flags for development teams. Easily roll out and roll back features in any application without code deploys. Mitigate risk for every feature on your roadmap. Learn more at https://www.optimizely.com/rollouts/, or see the [documentation](https://docs.developers.optimizely.com/rollouts/docs). - ## Getting Started -To get started with Optimizely Agent, follow the [getting started guide](./docs/getting-started.md) and view example -usage in our [examples folder](./examples). +To get started with Optimizely Agent, follow the [Quickstart guide](https://docs.developers.optimizely.com/full-stack/docs/) and view example usage in our [examples folder](./examples). ## Prerequisites Optimizely Agent is implemented in [Golang](https://golang.org/). Golang version 1.13+ is required for developing and compiling from source. @@ -275,10 +272,10 @@ go tool pprof http://localhost:6060/debug/pprof/mutex To view all available profiles can be found at [http://localhost:8088/debug/pprof/](http://localhost:8088/debug/pprof/) in your browser. ## Authorization -Optimizely Agent supports authorization workflows based on OAuth and JWT standards, allowing you to protect access to its API and Admin interfaces. For details, see the [Authorization Guide](./docs/auth.md). +Optimizely Agent supports authorization workflows based on OAuth and JWT standards, allowing you to protect access to its API and Admin interfaces. For details, see [Authorization Guide](https://docs.developers.optimizely.com/full-stack/docs/authorization). ## Notifications -Just as you can use Notification Listeners to subscribe to events of interest with Optimizely SDKs, you can use the Notifications endpoint to subscribe to events in Agent. For more information, see the [Notifications Guide](./docs/notifications.md). +Just as you can use Notification Listeners to subscribe to events of interest with Optimizely SDKs, you can use the Notifications endpoint to subscribe to events in Agent. For more information, see the [Notifications Guide](https://docs.developers.optimizely.com/full-stack/docs/agent-notifications). ## Package Structure Following best practice for go project layout as defined [here](https://github.com/golang-standards/project-layout) @@ -353,7 +350,7 @@ License (MIT): github.com/stretchr/testify net (c) 2009 The Go Authors License (BSD 3-Clause): https://github.com/golang/net - + sync (c) 2009 The Go Authors License (BSD 3-Clause): https://github.com/golang/sync @@ -365,7 +362,7 @@ License (Apache 2): github.com/rakyll/statik v0.1.7 sys (c) 2009 The Go Authors License (BSD 3-Clause): https://github.com/golang/sys - + ## Apache Copyright Notice Copyright 2019-present, Optimizely, Inc. and contributors diff --git a/docs/auth.md b/docs/auth.md deleted file mode 100644 index a35689cf..00000000 --- a/docs/auth.md +++ /dev/null @@ -1,115 +0,0 @@ -# Authorization Guide - -## Overview - -Optimizely Agent supports authorization workflows based on OAuth and JWT standards, allowing you to protect access to its API and Admin interfaces. - -There are three modes of operation: - -### Issuer & Validator -Access tokens are issued by Agent itself, using a [Client Credentials grant](https://www.oauth.com/oauth2-servers/access-tokens/client-credentials/). Access tokens are signed and validated using the HS256 algorithm with a signing secret provided in configuration. Clients request access tokens by sending a `POST` request to `/oauth/token` on the port of the desired interface (by default, `8080` for the API interface, and `8088` for the Admin interface), including a client ID and secret in the request. - - -Issuer & Validator mode is useful if you want to implement authorization, and you are not already running an authorization server that can issue JWTs. - -### Validator-only -Agent validates access tokens that were issued elsewhere. Access tokens are validated with public keys fetched from a [JWKS](https://tools.ietf.org/html/rfc7517) URL provided in configuration. - -Validator-only mode is useful if you want to plug directly into an existing JWT-based workflow already being used in your system or organization. - -### No authorization (default) -The interface is publicly available. - -## Configuration -- The API and Admin interfaces are each independently configured to run in one of the above-mentioned modes of operation. -- Authorization configuration is located under the `auth` key -- Each mode of operation has its own set of configuration properties, described below. - -### Issuer & Validator -The configuration properties pertaining to Issuer & Validator mode are listed below: - -|Property Name|Environment Variable|Description| -|---|---|---| -|ttl|TTL|Time-to-live of access tokens issued| -|hmacSecrets|OPTIMIZELY_ADMIN_AUTH_HMACSECRETS or OPTIMIZELY_API_AUTH_HMACSECRETS|Array of secrets used to sign & validate access tokens, using the HMAC SHA256 algorithm. Values must be base64-format strings. The first value in the array is used to sign issued access tokens. Access tokens signed with any value in the array are considered valid.| -|clients|N/A|Array of objects, used for token issuance, consisting of `id`, `secretHash`, and `sdkKeys`. Clients provide ID and secret in their requests to `/oauth/token`. Agent validates the request credentials by checking for an exact match of ID, checking that the BCrypt hash of the request secret matches the `secretHash` from configuration, and that the SDK key provided in the `X-Optimizely-Sdk-Key` request header exists in the `sdkKeys` from configuration. `secretHash` values must be base64-format strings.| - -#### generate_secret tool - -To make setup easier, Agent provides a command-line tool that can generate base64-encoded 32-byte random values, and their associated base64-encoded BCrypt hashes: -```shell script -// From the Agent root directory -> make generate_secret -Secret: i3SrdrCy/wEGqggv9OI4FgIsdHHNpOacrmIMJ6SFIkE= -Secret's hash: JDJhJDEyJERGNzhjRXVTNTdOQUZ3cndxTkZ6Li5XQURlazU2R21YeFZjb1pWSkN5eGZ1SXM4VXRLb0ZD -``` - -The generate_secret tool can be used for two purposes: -- These secrets can be used to set the `hmacSecrets` configuration value. -- These secrets can be used for authenticating access token requests to `/oauth/token`. Set the hash value as the `secretHash` configuration property (inside `clients`). Then, when making access token requests to `/oauth/token`, pass the secret value as `client_secret` in the request. For details of the access token issuance endpoint, see the [OpenAPI spec file](../api/openapi-spec/openapi.yaml) and the [auth example](../examples/auth.py). - - -The `generate_secret` command-line tool can be downloaded by navigating to Agent's latest [github release](https://github.com/optimizely/agent/releases) and choosing the binary appropriate for your OS architecture. - -### Validator-only -The configuration properties pertaining to Validator-only mode are listed below: - -|Property Name|Environment Variable|Description| -|---|---|---| -|jwksURL|JWKSURL|URL from which public keys should be fetched for token validation| -|jwksUpdateInterval|JWKSUPDATEINTERVAL|Interval on which public keys should be re-fetched (example: `30m` for 30 minutes)| - -### No authorization (default) -The API & Admin interfaces run with no authorization when no `auth` configuration is given. - -### Configuration examples -Optimizely Agent uses the [Viper](https://github.com/spf13/viper) library for configuration, which allows setting values via environment variables, flags, and YAML configuration files. -#### Issuer & Validator -_*WARNING*_: For security, we advise that you configure `hmacSecrets` with either an environment variable or a flag, and NOT through a config file. - -In the below example, the Admin interface is configured in Issuer & Validator mode, with `hmacSecrets` provided via environment variable, and other values provided via YAML config file. - -```shell script -// Comma-separated value, to set multiple hmacSecrets. -// Access tokens are signed with the first value. -// Access tokens are valid when they are signed with either of these values. -export OPTIMIZELY_ADMIN_AUTH_HMACSECRETS=QPtUGP/RqaXRltZf1QE1KxlF2Iuo09J0buZ3UNKeIr0,bkZAqSsZuM5NSnwEyO9Pzb6F8gGNu1BBuX/SpPaMeyM -``` - -```yaml -# config.yaml -admin: - auth: - # Access tokens will expire after 30 minutes - ttl: 30m - clients: - # Either of these two id/secret pairs can be exchanged for access tokens - - id: agentConsumer1 - secretHash: XgZTeTvWaZ6fLiey6EBSOxJ2QFdd6dIiUcZGDIIJ+IY - sdkKeys: - # These credentials can be exchanged for tokens granting access to these two SDK keys - - abcd1234 - - efgh5678 - - id: agentConsumer2 - secretHash: ssz0EEViKIinkFXxzqncKxz+6VygEc2d2rKf+la5rXM - sdkKeys: - # These credentials can be exchanged for tokens granting access only to this one SDK key - - ijkl9012 -``` -#### Validator-only -```yaml -# In this example, the API interface is configured in Validator-only mode -api: - auth: - # Signing keys will be fetched from this url and used when validating access tokens - jwksURL: https://YOUR_DOMAIN/.well-known/jwks.json - # Siging keys will be periodically fetched on this interval - jwksUpdateInterval: 30m -``` - -## Secret Rotation (Issuer & Validator mode) -To support secret rotation, both `hmacSecrets` and `clients` support setting multiple values. In `hmacSecrets`, the first value will be -used to sign issued tokens, but tokens signed with any of the values will be considered valid. - -## Example (Python) -For example requests demonstrating the Issuer & Validator mode, see [here](../examples/auth.py). diff --git a/docs/getting-started.md b/docs/readme-sync/deploy-as-a-microservice/012 - quickstart-with-docker.md similarity index 87% rename from docs/getting-started.md rename to docs/readme-sync/deploy-as-a-microservice/012 - quickstart-with-docker.md index 67e788cd..629c0881 100644 --- a/docs/getting-started.md +++ b/docs/readme-sync/deploy-as-a-microservice/012 - quickstart-with-docker.md @@ -1,6 +1,15 @@ -# Getting Started Guide - -This is a brief guide showing how to run Agent locally via Docker and how to access some of the common API endpoints. +--- +title: "Quickstart with Docker" +excerpt: "" +slug: "quickstart-with-docker" +hidden: true +metadata: + title: "Agent Quickstart with Docker - Optimizely Full Stack" +createdAt: "2020-05-21T20:35:58.387Z" +updatedAt: "2020-07-14T20:51:52.458Z" +--- + +This is a brief quickstart showing how to run Agent locally via Docker and how to access some of the common API endpoints. If Docker is not installed then you can download it [here](https://docs.docker.com/install/). ## Running locally via Docker @@ -57,4 +66,4 @@ resp = s.post(url = 'http://localhost:8080/v1/activate', params=params, json=pay print(resp.json()) ``` -The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. +The activate API is a POST to signal to the caller that there are side-effects. Namely, activation results in a "decision" event sent to Optimizely analytics for the purpose of analyzing Feature Test results. A "decision" will NOT be sent if the feature is simply part of a rollout. diff --git a/docs/readme-sync/deploy-as-a-microservice/020 - setup-optimizely-agent.md b/docs/readme-sync/deploy-as-a-microservice/020 - setup-optimizely-agent.md index 4b7a58fc..23de9d44 100644 --- a/docs/readme-sync/deploy-as-a-microservice/020 - setup-optimizely-agent.md +++ b/docs/readme-sync/deploy-as-a-microservice/020 - setup-optimizely-agent.md @@ -1,10 +1,10 @@ --- -title: "Set up Optimizely Agent" +title: "Install Optimizely Agent" excerpt: "" slug: "setup-optimizely-agent" hidden: false metadata: - title: "Getting started with Agent - Optimizely Full Stack" + title: "Install Agent - Optimizely Full Stack" createdAt: "2020-02-21T17:44:27.363Z" updatedAt: "2020-03-31T23:54:17.841Z" --- diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/010 -authorization.md b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md similarity index 100% rename from docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/010 -authorization.md rename to docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/010 - authorization.md diff --git a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md index c31b48ed..cbd14cb3 100644 --- a/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md +++ b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/020 - webhooks-agent.md @@ -34,4 +34,8 @@ webhook: # secret: # ## skipSignatureCheck: override the signature check (not recommended for production) # skipSignatureCheck: true -``` \ No newline at end of file +``` + +## Next + +[Create Webhooks](https://docs.developers.optimizely.com/full-stack/docs/webhooks-agent) diff --git a/docs/notifications.md b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md similarity index 87% rename from docs/notifications.md rename to docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md index 1da7746b..30ca08bd 100644 --- a/docs/notifications.md +++ b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/031 - agent-notifications.md @@ -1,4 +1,14 @@ -# Notifications Guide +--- +title: Agent Notifications" +excerpt: "" +slug: "agent-notifications" +hidden: false +metadata: + title: "Agent notifications - Optimizely Full Stack" +createdAt: "2020-05-21T20:35:58.387Z" +updatedAt: "2020-07-14T20:51:52.458Z" +--- + Agent provides an endpoint that sends notifications to subscribers via [Server-Sent Events](https://developer.mozilla.org/en-US/docs/Web/API/Server-sent_events). This is Agent's equivalent of Notification Listeners found in Optimizely SDKs. diff --git a/docs/advanced-configuration.md b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md similarity index 93% rename from docs/advanced-configuration.md rename to docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md index ad6c4fbb..5d22cce9 100644 --- a/docs/advanced-configuration.md +++ b/docs/readme-sync/deploy-as-a-microservice/040 - configure-optimizely-agent/040 - advanced-configuration.md @@ -31,7 +31,7 @@ export OPTIMIZELY_CLIENT_POLLINGINTERVAL=120s ``` ## Unsupported Environment Variable Options -Some options can only be set via config file, and not environment variable (for details on these options, see the Configuration Options table in the [main README](../README.md)): +Some options can only be set via config file, and not environment variable (for details on these options, see the Configuration Options table in the [main README](https://github.com/optimizely/agent/blob/master/README.md): - `admin.auth.clients` - `api.auth.clients` - Options under`webhook.projects`