{"id":13704942,"url":"https://github.com/temporalio/web","last_synced_at":"2025-05-05T12:32:46.871Z","repository":{"id":36986135,"uuid":"215841172","full_name":"temporalio/web","owner":"temporalio","description":"Temporal Web UI v1","archived":true,"fork":false,"pushed_at":"2023-05-25T01:15:36.000Z","size":1995,"stargazers_count":70,"open_issues_count":90,"forks_count":52,"subscribers_count":13,"default_branch":"master","last_synced_at":"2024-11-13T12:41:03.024Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":"","language":"JavaScript","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/temporalio.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null}},"created_at":"2019-10-17T16:47:12.000Z","updated_at":"2023-11-01T01:52:42.000Z","dependencies_parsed_at":"2024-04-11T06:49:22.799Z","dependency_job_id":"20c42c6a-14c2-49b3-83ec-561572060ce3","html_url":"https://github.com/temporalio/web","commit_stats":null,"previous_names":["temporalio/temporal-web"],"tags_count":39,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fweb","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fweb/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fweb/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/temporalio%2Fweb/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/temporalio","download_url":"https://codeload.github.com/temporalio/web/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":252497705,"owners_count":21757666,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":[],"created_at":"2024-08-02T22:00:27.446Z","updated_at":"2025-05-05T12:32:46.541Z","avatar_url":"https://github.com/temporalio.png","language":"JavaScript","funding_links":[],"categories":["Cadence"],"sub_categories":[],"readme":"# Temporal Web UI\n\n[![Build status](https://badge.buildkite.com/72da2011c93761d680bc8c641d07adad16c94b99b0ed8d7566.svg?branch=master)](https://buildkite.com/temporal/temporal-web)\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftemporalio%2Ftemporal-web.svg?type=shield)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftemporalio%2Ftemporal-web?ref=badge_shield)\n\n\u003e **Nota bene**: Temporal Web UI v1 has been deprecated since September 30, 2022. Temporal Web UI v2 is now generally available https://docs.temporal.io/web-ui/\n\nTemporal is a distributed, scalable, durable, and highly available orchestration engine we developed at Uber Engineering to execute asynchronous long-running business logic in a scalable and resilient way.\n\nThis web UI is used to view workflows from [Temporalio][temporal], see what's running, and explore and debug workflow executions.\n\nFor a **video demo** of how this looks, you can [check our docs](https://docs.temporal.io/docs/java-run-your-first-app/#state-visibility).\n\n## Getting Started\n\n### Configuration\n\nSet these environment variables if you need to change their defaults\n\n| Variable                         | Description                                                       | Default                       |\n| -------------------------------- | ----------------------------------------------------------------- | ----------------------------- |\n| TEMPORAL_GRPC_ENDPOINT           | String representing server gRPC endpoint                          | 127.0.0.1:7233                |\n| TEMPORAL_WEB_PORT                | HTTP port to serve on                                             | 8088                          |\n| TEMPORAL_CONFIG_PATH             | Path to config file, see [configurations](#configuring-authentication-optional) | ./server/config.yml |\n| TEMPORAL_PERMIT_WRITE_API        | Boolean to permit write API methods such as Terminating Workflows | true                          |\n| TEMPORAL_WEB_ROOT_PATH           | The root path to serve the app under. Ex. \"/test/\"                | /                             |\n| TEMPORAL_HOT_RELOAD_PORT         | HTTP port used by hot reloading in development                    | 8081                          |\n| TEMPORAL_HOT_RELOAD_TEST_PORT    | HTTP port used by hot reloading in tests                          | 8082                          |\n| TEMPORAL_SESSION_SECRET          | Secret used to hash the session with HMAC                         | \"ensure secret in production\" |\n| TEMPORAL_EXTERNAL_SCRIPTS        | Additional JavaScript tags to serve in the UI                     |                               |\n| TEMPORAL_GRPC_MAX_MESSAGE_LENGTH | gRPC max message length (bytes)                                   | 4194304 (4mb)                 |\n| TEMPORAL_CODEC_ENDPOINT          | Codec Endpoint, explained below                                   |                               |\n| TEMPORAL_CODEC_PASS_ACCESS_TOKEN | Send OIDC access token to Codec Server                            | false                         |\n\n\n\u003cdetails\u003e\n\u003csummary\u003e\nOptional TLS configuration variables:\n\u003c/summary\u003e\n\n| Variable                              | Description                                                         | Default |\n| ------------------------------------- | ------------------------------------------------------------------- | ------- |\n| TEMPORAL_TLS_CERT_PATH                | Certificate for the server to validate the client (web) identity    |         |\n| TEMPORAL_TLS_KEY_PATH                 | Private key for secure communication with the server                |         |\n| TEMPORAL_TLS_CA_PATH                  | Certificate authority (CA) certificate for the validation of server |         |\n| TEMPORAL_TLS_ENABLE_HOST_VERIFICATION | Enables verification of the server certificate                      | true    |\n| TEMPORAL_TLS_SERVER_NAME              | Target server that is used for TLS host verification                |         |\n| TEMPORAL_TLS_REFRESH_INTERVAL         | How often to refresh TLS Certs, seconds                             | 0       |\n| TEMPORAL_WEB_TLS_CERT_PATH            | Certificate used to support HTTPS in the temporal web UI            |         |\n| TEMPORAL_WEB_TLS_KEY_PATH             | Private key for supporting HTTPS in the temporal web UI             |         |\n\n* To enable mutual TLS, you need to specify `TEMPORAL_TLS_KEY_PATH` and `TEMPORAL_TLS_CERT_PATH`.\n* For server-side TLS you need to specify only `TEMPORAL_TLS_CA_PATH`.\n* To Enable HTTPS in the temporal web UI, specify a `TEMPORAL_WEB_TLS_CERT_PATH` and a `TEMPORAL_WEB_TLS_CERT_PATH` value.\n\nBy default we will also verify your server `hostname`, matching it to `TEMPORAL_TLS_SERVER_NAME`. You can turn this off by setting `TEMPORAL_TLS_ENABLE_HOST_VERIFICATION` to `false`.\n\nSetting `TEMPORAL_TLS_REFRESH_INTERVAL` will make the TLS certs reload every N seconds.\n\n\u003c/details\u003e\n\n### Configuring a Codec Endpoint (optional)\n\nIf you are using a codec on your workers to encrypt or compress Temporal Payloads you may wish to deploy a codec server so that your users can see the decoded Payloads while using Temporal Web. The samples for the Temporal SDK you are using for your application should include examples of how to build a codec server. Please let us know if this is not the case. Once you have a codec server running you can configure Temporal Web to use it to decode Payloads for a user in 2 ways:\n\n1. Edit the `server/config.yml` file:\n\n    ```yaml\n    codec:\n      endpoint: https://codec.myorg.com\n    ```\n2. Set the environment variable TEMPORAL_CODEC_ENDPOINT to the URL for your remote codec server. This is often a more convenient option when running Temporal Web in a docker container.\n\nTemporal Web will then configure it's UI to decode Payloads as appropriate via the codec.\n\nPlease note that requests to the codec server will be made from the user's browser directly, not via Temporal Web's server. This means that the Temporal Web server will never see the decoded Payloads and does not need to be able to connect to the codec server. This allows using codec servers on internal and secure networks while using an externally hosted Temporal Web instance, such that provided by Temporal Cloud.\n\n### Configuring Authentication (optional)\n\n**Note** For proper security, your server needs to be secured as well and validate the JWT tokens that Temporal Web will be sending to server once users are authenticated. See [security docs](https://docs.temporal.io/docs/server/security/#authorization) for details\n\nSince v1.3, Temporal Web offers optional OAuth SSO authentication. You can enable it in 2 steps:\n\n1. Edit the `server/config.yml` file:\n\n    ```yaml\n    auth:\n      enabled: true # Temporal Web checks this first before reading your provider config\n      providers:\n          - label: 'Auth0 oidc'                        # for internal use; in future may expose as button text\n            type: oidc                                  # for futureproofing; only oidc is supported today\n            issuer: https://myorg.us.auth0.com\n            client_id: xxxxxxxxxxxxxxxxxxxx\n            client_secret: xxxxxxxxxxxxxxxxxxxx\n            scope: openid profile email\n            audience: # identifier of the audience for an issued token (optional)\n            callback_base_uri: http://localhost:8088\n            pass_id_token: false # adds ID token as 'authorization-extras' header with every request to server\n    ```\n\n    \u003cdetails\u003e\n    \u003csummary\u003e\n    Providing \u003ccode\u003econfig.yml\u003c/code\u003e to Docker image\n    \u003c/summary\u003e\n\n\n    If you are running Temporal Web from the docker image, you can provide your external config.yml to docker to override the internal config. \n    Create config.yml file on your machine, for example at `~/Desktop/config.yml`. \n    Start the docker image, providing the path to your config.yml file using external volume flag (-v). Leave the path after the semicolon as is: \n\n    ```bash\n    docker run --network host -v ~/Desktop/config.yml:/usr/app/server/config.yml temporalio/web:latest\n    ```\n\n    \u003c/details\u003e\n\n    In future, multiple Oauth providers may be supported, however for now we only read the first Oauth provider under the `providers` key above.\n\n    Common Oauth Providers and their docs:\n    - Auth0: https://auth0.com/docs/protocols/configure-okta-as-oauth2-identity-provider\n    - Okta: https://help.okta.com/en/prod/Content/Topics/Apps/Apps_App_Integration_Wizard_OIDC.htm\n        \u003cdetails\u003e\n          \u003csummary\u003e\n            Troubleshooting note for Okta users:\n          \u003c/summary\u003e\n          Some providers like Okta, have a race condition that may cause logins to occasionally fail. You can get around this by providing the full URL to the `openid-configuration` path as part of the `issuer` parameter:\n\n        ```yaml\n          auth:\n            enabled: true\n            providers:\n                - label: 'okta dev'\n                  type: oidc\n                  issuer: https://dev-xxxxxxx.okta.com/.well-known/openid-configuration\n                  ...\n        ```\n      \u003c/details\u003e\n    - Keycloak: https://www.keycloak.org/getting-started/getting-started-docker\n    - LoginRadius: https://www.loginradius.com/docs/developer/guide/oauth/\n    - please feel free to [PR or request more help on the Temporal Web repo](https://github.com/temporalio/web/)\n\n2. You will need to provide a redirect URL to your Oauth Provider. If you are hosting Temporal Web at `http://localhost:8088` (this is configured by `callback_base_uri` in `server/config.yml`), then it is `http://localhost:8088/auth/sso_callback`. \n\n    - By default, Temporal Web asks for 3 scopes, make sure your provider recognizes these or you may see scope-related errors:\n      - `openid` required by some OIDC providers like [auth0](https://auth0.com/docs/scopes/openid-connect-scopes)\n      - `profile` for name\n      - `email` for email\n\n### Running locally\n\n`temporal-web` uses all the standard [npm scripts](https://docs.npmjs.com/misc/scripts) to install dependencies, run the server, and run tests. Additionally to run locally with webpack hot reloading and other conveniences, use\n\n```\nmake\nnpm run dev\n```\n\nYou can then access Temporal Web at `localhost:8088` (you can configure both the port and the path with `TEMPORAL_WEB_PORT` and `TEMPORAL_WEB_ROOT_PATH` per the config docs above).\n\nFor development and contributing to `temporal-web`, please see the [contributing guide](https://github.com/temporalio/temporal-web/blob/master/CONTRIBUTING.md).\n\nYou may also use docker by pulling [temporalio/web](https://hub.docker.com/r/temporalio/web/). It is also included in the Temporal server's [local docker setup](https://github.com/temporalio/temporal/tree/master/docker).\n\n### API\n\nIf you need to extend `temporal-web` to add middleware to the server, you can install `temporal-web` as a dependency, and it will export the [Koa](http://koajs.com/) web server that has not yet been started or configured. It includes an additional `init` function that will then compose the built-in middleware. This gives you an option to add middleware before or after you call `init` so it will add the middleware at the beginning or the end of the chain, respectively.\n\n#### `init(options)`\n\nAll options are optional.\n\n`useWebpack`: If `true`, starts webpack and adds the middleware, otherwise if `false`, it assumes the UI bundle was already built and serves it statically. Defaults to `process.env.NODE_ENV === 'production'`.\n\n`logErrors`: If `true`, thrown errors are logged to `console.error`. Defaults to `true`.\n\nFor example, here is how you would add a request count metric using `uber-statsd-client`:\n\n```javascript\nvar app = require('temporal-web');\nvar createStatsd = require('uber-statsd-client');\nvar sdc = createStatsd({\n  host: 'statsd.example.com',\n});\n\napp\n  .use(async function(ctx, next) {\n    sdc.increment('http.request');\n    await next();\n  })\n  .init()\n  .listen(7000);\n```\n\nThe [webpack](https://webpack.js.org/) configuration is also exported as `webpackConfig`, and can be modified before calling `init()`.\n\n### Licence\n\nMIT License, please see [LICENSE](https://github.com/temporalio/temporal-web/blob/master/LICENSE) for details.\n\n[temporal]: https://github.com/temporalio/temporal\n\n[![FOSSA Status](https://app.fossa.com/api/projects/git%2Bgithub.com%2Ftemporalio%2Ftemporal-web.svg?type=large)](https://app.fossa.com/projects/git%2Bgithub.com%2Ftemporalio%2Ftemporal-web?ref=badge_large)\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftemporalio%2Fweb","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ftemporalio%2Fweb","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ftemporalio%2Fweb/lists"}