Skip to content

Commit 8568580

Browse files
authored
feat: add custom ingestion key via INGESTION_API_KEY (#1112)
Closes HDX-2283 This adds an environment variable `INGESTION_API_KEY` that can be set by the user. This apiKey will be valid and accepted by the Otel collector. It is in addition to the autogenerated apiKey and will not show in the team settings apiKey section.
1 parent b6787d5 commit 8568580

File tree

6 files changed

+22
-0
lines changed

6 files changed

+22
-0
lines changed

.changeset/chatty-poets-camp.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"@hyperdx/api": patch
3+
---
4+
5+
feat: INGESTION_API_KEY allows for environment variable defined api key

docker/hyperdx/entry.local.base.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ export MONGO_URI="mongodb://db:27017/hyperdx"
1818
export OPAMP_SERVER_URL="http://127.0.0.1:${OPAMP_PORT}"
1919
export CLICKHOUSE_PROMETHEUS_METRICS_ENDPOINT="${CLICKHOUSE_PROMETHEUS_METRICS_ENDPOINT:-ch-server:9363}"
2020

21+
export HYPERDX_IMAGE=$([[ "${IS_LOCAL_APP_MODE}" == "DANGEROUSLY_is_local_app_mode💀" ]] && echo "all-in-one" || echo "all-in-one-noauth")
2122
export EXPRESS_SESSION_SECRET="hyperdx is cool 👋"
2223
# IS_LOCAL_APP_MODE should be set by the calling script
2324
# Default to dangerous mode if not set

docker/hyperdx/entry.prod.sh

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
export FRONTEND_URL="${FRONTEND_URL:-${HYPERDX_APP_URL:-http://localhost}:${HYPERDX_APP_PORT:-8080}}"
44
export OPAMP_PORT=${HYPERDX_OPAMP_PORT:-4320}
5+
export HYPERDX_IMAGE="hyperdx"
56

67
# Set to "REQUIRED_AUTH" to enforce API authentication.
78
# ⚠️ Do not change this value !!!!

packages/api/.env.development

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,3 +23,5 @@ NODE_OPTIONS="--max-http-header-size=131072"
2323
ENABLE_SWAGGER=true
2424
DEFAULT_CONNECTIONS=[{"name":"Local ClickHouse","host":"http://localhost:8123","username":"default","password":""}]
2525
DEFAULT_SOURCES=[{"from":{"databaseName":"default","tableName":"otel_logs"},"kind":"log","timestampValueExpression":"TimestampTime","name":"Logs","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"Body","serviceNameExpression":"ServiceName","bodyExpression":"Body","eventAttributesExpression":"LogAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,SeverityText,Body","severityTextExpression":"SeverityText","traceIdExpression":"TraceId","spanIdExpression":"SpanId","connection":"Local ClickHouse","traceSourceId":"Traces","sessionSourceId":"Sessions","metricSourceId":"Metrics"},{"from":{"databaseName":"default","tableName":"otel_traces"},"kind":"trace","timestampValueExpression":"Timestamp","name":"Traces","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"SpanName","serviceNameExpression":"ServiceName","bodyExpression":"SpanName","eventAttributesExpression":"SpanAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,StatusCode,round(Duration/1e6),SpanName","traceIdExpression":"TraceId","spanIdExpression":"SpanId","durationExpression":"Duration","durationPrecision":9,"parentSpanIdExpression":"ParentSpanId","spanNameExpression":"SpanName","spanKindExpression":"SpanKind","statusCodeExpression":"StatusCode","statusMessageExpression":"StatusMessage","connection":"Local ClickHouse","logSourceId":"Logs","sessionSourceId":"Sessions","metricSourceId":"Metrics"},{"from":{"databaseName":"default","tableName":""},"kind":"metric","timestampValueExpression":"TimeUnix","name":"Metrics","resourceAttributesExpression":"ResourceAttributes","metricTables":{"gauge":"otel_metrics_gauge","histogram":"otel_metrics_histogram","sum":"otel_metrics_sum","_id":"682586a8b1f81924e628e808","id":"682586a8b1f81924e628e808"},"connection":"Local ClickHouse","logSourceId":"Logs","traceSourceId":"Traces","sessionSourceId":"Sessions"},{"from":{"databaseName":"default","tableName":"hyperdx_sessions"},"kind":"session","timestampValueExpression":"TimestampTime","name":"Sessions","displayedTimestampValueExpression":"Timestamp","implicitColumnExpression":"Body","serviceNameExpression":"ServiceName","bodyExpression":"Body","eventAttributesExpression":"LogAttributes","resourceAttributesExpression":"ResourceAttributes","defaultTableSelectExpression":"Timestamp,ServiceName,SeverityText,Body","severityTextExpression":"SeverityText","traceIdExpression":"TraceId","spanIdExpression":"SpanId","connection":"Local ClickHouse","logSourceId":"Logs","traceSourceId":"Traces","metricSourceId":"Metrics"}]
26+
INGESTION_API_KEY="super-secure-ingestion-api-key"
27+
HYPERDX_API_KEY=$INGESTION_API_KEY

packages/api/src/config.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ export const EXPRESS_SESSION_SECRET = (env.EXPRESS_SESSION_SECRET ||
1515
DEFAULT_EXPRESS_SESSION) as string;
1616
export const FRONTEND_URL = (env.FRONTEND_URL ||
1717
DEFAULT_FRONTEND_URL) as string;
18+
const HYPERDX_IMAGE = env.HYPERDX_IMAGE;
19+
export const IS_APP_IMAGE = HYPERDX_IMAGE === 'hyperdx';
20+
export const IS_ALL_IN_ONE_IMAGE = HYPERDX_IMAGE === 'all-in-one-auth';
21+
export const IS_LOCAL_IMAGE = HYPERDX_IMAGE === 'all-in-one-noauth';
22+
export const INGESTION_API_KEY = env.INGESTION_API_KEY ?? '';
1823
export const HYPERDX_API_KEY = env.HYPERDX_API_KEY as string;
1924
export const HYPERDX_LOG_LEVEL = env.HYPERDX_LOG_LEVEL as string;
2025
export const IS_CI = NODE_ENV === 'test';

packages/api/src/opamp/controllers/opampController.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,14 @@ type CollectorConfig = {
116116

117117
export const buildOtelCollectorConfig = (teams: ITeam[]): CollectorConfig => {
118118
const apiKeys = teams.filter(team => team.apiKey).map(team => team.apiKey);
119+
120+
if (config.IS_ALL_IN_ONE_IMAGE || config.IS_LOCAL_APP_MODE || config.IS_DEV) {
121+
// Only allow INGESTION_API_KEY for dev or all-in-one images for security reasons
122+
if (config.INGESTION_API_KEY) {
123+
apiKeys.push(config.INGESTION_API_KEY);
124+
}
125+
}
126+
119127
const collectorAuthenticationEnforced =
120128
teams[0]?.collectorAuthenticationEnforced;
121129

0 commit comments

Comments
 (0)