-
Notifications
You must be signed in to change notification settings - Fork 0
feat: Superset embedded dashboard config #633
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
Add the configuration required to embed Superset dashboards in other services. Authentication from the service will be performed with a dedicated Superset service user.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Pull request overview
This PR adds configuration for embedding Superset dashboards in external services using JWT-based guest token authentication. The changes introduce a new secret (GUEST_TOKEN_JWT_SECRET) that will be used to sign JWT tokens for embedded dashboard access through a dedicated service user with read-only guest permissions.
Key Changes:
- Adds JWT secret configuration for Superset embedded dashboard authentication
- Enables the
EMBEDDED_SUPERSETfeature flag in Superset configuration - Wires the new secret through Terraform/Terragrunt infrastructure and CI/CD workflows
Reviewed changes
Copilot reviewed 7 out of 7 changed files in this pull request and generated 1 comment.
Show a summary per file
| File | Description |
|---|---|
| terragrunt/aws/variables.tf | Defines new Terraform variable for guest token JWT secret |
| terragrunt/aws/ecs.tf | Creates SSM parameter for JWT secret and adds it to ECS container secrets and IAM policy |
| docker/superset_config.py | Configures Superset embedded dashboard authentication with JWT settings and enables feature flag |
| .github/workflows/tf-plan-staging.yml | Adds JWT secret environment variable for staging Terraform plan |
| .github/workflows/tf-plan-prod.yml | Adds JWT secret environment variable for production Terraform plan |
| .github/workflows/tf-apply-staging.yml | Adds JWT secret environment variable for staging Terraform apply |
| .github/workflows/tf-apply-prod.yml | Adds JWT secret environment variable for production Terraform apply |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
Staging✅ Terraform Init: Plan: 5 to add, 6 to change, 4 to destroyShow summary
✂ Warning: plan has been truncated! See the full plan in the logs. Show planResource actions are indicated with the following symbols:
+ create
~ update in-place
-/+ destroy and then create replacement
<= read (data resources)
Terraform will perform the following actions:
# data.aws_iam_policy_document.ecs_task_ssm_parameters will be read during apply
# (config refers to values not yet known)
<= data "aws_iam_policy_document" "ecs_task_ssm_parameters" {
+ id = (known after apply)
+ json = (known after apply)
+ minified_json = (known after apply)
+ statement {
+ actions = [
+ "ssm:GetParameter",
+ "ssm:GetParameters",
]
+ effect = "Allow"
+ resources = [
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/ecs-cwagent",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/google_oauth_client_id",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/google_oauth_client_secret",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/slack_api_token",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_password",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_user",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_host",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_password",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_username",
+ "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_secret_key",
+ (known after apply),
]
+ sid = "GetSSMParameters"
}
}
# aws_ecs_task_definition.superset_upgrade must be replaced
-/+ resource "aws_ecs_task_definition" "superset_upgrade" {
~ arn = "arn:aws:ecs:ca-central-1:257394494478:task-definition/superset-upgrade:12" -> (known after apply)
~ arn_without_revision = "arn:aws:ecs:ca-central-1:257394494478:task-definition/superset-upgrade" -> (known after apply)
~ container_definitions = jsonencode(
[
- {
- command = [
- "/app/docker/docker-bootstrap.sh",
- "upgrade",
]
- cpu = 1024
- environment = [
- {
- name = "CACHE_WARMUP_EXECUTORS"
- value = "cache-warmer"
},
- {
- name = "FLASK_DEBUG"
- value = "true"
},
- {
- name = "GUNICORN_KEEPALIVE"
- value = "120"
},
- {
- name = "REDIS_HOST"
- value = "master.superset-cache-staging.wv1cbb.cac1.cache.amazonaws.com"
},
- {
- name = "REDIS_PORT"
- value = "6379"
},
- {
- name = "SMTP_HOST"
- value = "email-smtp.ca-central-1.amazonaws.com"
},
- {
- name = "SMTP_MAIL_FROM"
- value = "[email protected]"
},
- {
- name = "SUPERSET_DATABASE_DB"
- value = "superset"
},
- {
- name = "WEBDRIVER_BASEURL"
- value = "http://superset.superset.ecs.local:8088"
},
- {
- name = "WEBDRIVER_BASEURL_USER_FRIENDLY"
- value = "https://superset.cdssandbox.xyz"
},
]
- essential = true
- image = "257394494478.dkr.ecr.ca-central-1.amazonaws.com/superset:latest"
- linuxParameters = {
- capabilities = {
- add = []
- drop = [
- "ALL",
]
}
}
- logConfiguration = {
- logDriver = "awslogs"
- options = {
- awslogs-group = "/aws/ecs/superset/superset"
- awslogs-region = "ca-central-1"
- awslogs-stream-prefix = "upgrade"
}
}
- memory = 2048
- mountPoints = []
- name = "superset-upgrade"
- portMappings = [
- {
- containerPort = 8088
- hostPort = 8088
- protocol = "tcp"
},
]
- secrets = [
- {
- name = "SLACK_API_TOKEN"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/slack_api_token"
},
- {
- name = "SMTP_PASSWORD"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_password"
},
- {
- name = "SMTP_USER"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_user"
},
- {
- name = "SUPERSET_DATABASE_HOST"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_host"
},
- {
- name = "SUPERSET_DATABASE_PASSWORD"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_password"
},
- {
- name = "SUPERSET_DATABASE_USER"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_username"
},
- {
- name = "SUPERSET_SECRET_KEY"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_secret_key"
},
]
- systemControls = []
- volumesFrom = []
},
]
) -> (known after apply) # forces replacement
~ enable_fault_injection = false -> (known after apply)
~ id = "superset-upgrade" -> (known after apply)
~ revision = 12 -> (known after apply)
tags = {
"CostCentre" = "cds-superset-staging"
"Terraform" = "true"
}
# (13 unchanged attributes hidden)
# (1 unchanged block hidden)
}
# aws_ssm_parameter.guest_token_jwt_secret will be created
+ resource "aws_ssm_parameter" "guest_token_jwt_secret" {
+ arn = (known after apply)
+ data_type = (known after apply)
+ has_value_wo = (known after apply)
+ id = (known after apply)
+ insecure_value = (known after apply)
+ key_id = (known after apply)
+ name = "guest_token_jwt_secret"
+ region = "ca-central-1"
+ tags = {
+ "CostCentre" = "cds-superset-staging"
+ "Terraform" = "true"
}
+ tags_all = {
+ "CostCentre" = "cds-superset-staging"
+ "Terraform" = "true"
}
+ tier = (known after apply)
+ type = "SecureString"
+ value = (sensitive value)
+ version = (known after apply)
}
# module.celery_beat_ecs.data.aws_ecs_task_definition.this_latest will be read during apply
# (depends on a resource or a module with changes pending)
<= data "aws_ecs_task_definition" "this_latest" {
+ arn = (known after apply)
+ arn_without_revision = (known after apply)
+ container_definitions = (known after apply)
+ cpu = (known after apply)
+ enable_fault_injection = (known after apply)
+ ephemeral_storage = (known after apply)
+ execution_role_arn = (known after apply)
+ family = (known after apply)
+ id = (known after apply)
+ ipc_mode = (known after apply)
+ memory = (known after apply)
+ network_mode = (known after apply)
+ pid_mode = (known after apply)
+ placement_constraints = (known after apply)
+ proxy_configuration = (known after apply)
+ region = (known after apply)
+ requires_compatibilities = (known after apply)
+ revision = (known after apply)
+ runtime_platform = (known after apply)
+ status = (known after apply)
+ task_definition = "celery-beat"
+ task_role_arn = (known after apply)
+ volume = (known after apply)
}
# module.celery_beat_ecs.data.aws_iam_policy_document.this_task_exec_combined will be read during apply
# (config refers to values not yet known)
<= data "aws_iam_policy_document" "this_task_exec_combined" {
+ id = (known after apply)
+ json = (known after apply)
+ minified_json = (known after apply)
+ source_policy_documents = [
+ jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "ecr:GetDownloadUrlForLayer",
+ "ecr:GetAuthorizationToken",
+ "ecr:BatchGetImage",
+ "ecr:BatchCheckLayerAvailability",
]
+ Effect = "Allow"
+ Resource = "*"
},
]
+ Version = "2012-10-17"
}
),
+ jsonencode(
{
+ Statement = [
+ {
+ Action = "logs:DescribeLogGroups"
+ Effect = "Allow"
+ Resource = "*"
},
+ {
+ Action = [
+ "logs:PutLogEvents",
+ "logs:DescribeLogStreams",
+ "logs:CreateLogStream",
]
+ Effect = "Allow"
+ Resource = "arn:aws:logs:ca-central-1:257394494478:log-group:/aws/ecs/superset/celery-beat:*"
},
]
+ Version = "2012-10-17"
}
),
+ (known after apply),
+ jsonencode(
{
+ Statement = [
+ {
+ Action = [
+ "cloudwatch:PutMetricData",
+ "ec2:DescribeVolumes",
+ "ec2:DescribeTags",
+ "logs:PutLogEvents",
+ "logs:PutRetentionPolicy",
+ "logs:DescribeLogStreams",
+ "logs:DescribeLogGroups",
+ "logs:CreateLogStream",
+ "logs:CreateLogGroup",
+ "xray:PutTraceSegments",
+ "xray:PutTelemetryRecords",
+ "xray:GetSamplingRules",
+ "xray:GetSamplingTargets",
+ "xray:GetSamplingStatisticSummaries",
]
+ Effect = "Allow"
+ Resource = "*"
+ Sid = "CWACloudWatchServerPermissions"
},
+ {
+ Action = [
+ "ssm:GetParameter",
]
+ Effect = "Allow"
+ Resource = "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
+ Sid = "CWASSMServerPermissions"
},
]
+ Version = "2012-10-17"
}
),
]
}
# module.celery_beat_ecs.aws_ecs_service.this will be updated in-place
~ resource "aws_ecs_service" "this" {
id = "arn:aws:ecs:ca-central-1:257394494478:service/superset/celery-beat"
name = "celery-beat"
tags = {
"CostCentre" = "cds-superset-staging"
"Terraform" = "true"
}
~ task_definition = "celery-beat:120" -> (known after apply)
# (18 unchanged attributes hidden)
# (5 unchanged blocks hidden)
}
# module.celery_beat_ecs.aws_ecs_task_definition.this must be replaced
-/+ resource "aws_ecs_task_definition" "this" {
~ arn = "arn:aws:ecs:ca-central-1:257394494478:task-definition/celery-beat:117" -> (known after apply)
~ arn_without_revision = "arn:aws:ecs:ca-central-1:257394494478:task-definition/celery-beat" -> (known after apply)
~ container_definitions = jsonencode(
[
- {
- command = [
- "/app/docker/docker-bootstrap.sh",
- "beat",
]
- dependsOn = [
- {
- condition = "SUCCESS"
- containerName = "init"
},
]
- environment = [
- {
- name = "CACHE_WARMUP_EXECUTORS"
- value = "cache-warmer"
},
- {
- name = "FLASK_DEBUG"
- value = "true"
},
- {
- name = "GUNICORN_KEEPALIVE"
- value = "120"
},
- {
- name = "OTEL_AWS_APPLICATION_SIGNALS_ENABLED"
- value = "true"
},
- {
- name = "OTEL_AWS_APPLICATION_SIGNALS_EXPORTER_ENDPOINT"
- value = "http://localhost:4316/v1/metrics"
},
- {
- name = "OTEL_EXPORTER_OTLP_PROTOCOL"
- value = "http/protobuf"
},
- {
- name = "OTEL_EXPORTER_OTLP_TRACES_ENDPOINT"
- value = "http://localhost:4316/v1/traces"
},
- {
- name = "OTEL_LOGS_EXPORTER"
- value = "none"
},
- {
- name = "OTEL_METRICS_EXPORTER"
- value = "none"
},
- {
- name = "OTEL_PYTHON_CONFIGURATOR"
- value = "aws_configurator"
},
- {
- name = "OTEL_PYTHON_DISTRO"
- value = "aws_distro"
},
- {
- name = "OTEL_RESOURCE_ATTRIBUTES"
- value = "aws.log.group.names=/aws/ecs/superset/celery-beat,service.name=celery-beat"
},
- {
- name = "OTEL_TRACES_SAMPLER"
- value = "xray"
},
- {
- name = "OTEL_TRACES_SAMPLER_ARG"
- value = "endpoint=http://localhost:2000"
},
- {
- name = "PYTHONPATH"
- value = "/otel-auto-instrumentation-python/opentelemetry/instrumentation/auto_instrumentation:/app:/otel-auto-instrumentation-python"
},
- {
- name = "REDIS_HOST"
- value = "master.superset-cache-staging.wv1cbb.cac1.cache.amazonaws.com"
},
- {
- name = "REDIS_PORT"
- value = "6379"
},
- {
- name = "SMTP_HOST"
- value = "email-smtp.ca-central-1.amazonaws.com"
},
- {
- name = "SMTP_MAIL_FROM"
- value = "[email protected]"
},
- {
- name = "SUPERSET_DATABASE_DB"
- value = "superset"
},
- {
- name = "WEBDRIVER_BASEURL"
- value = "http://superset.superset.ecs.local:8088"
},
- {
- name = "WEBDRIVER_BASEURL_USER_FRIENDLY"
- value = "https://superset.cdssandbox.xyz"
},
]
- essential = true
- image = "257394494478.dkr.ecr.ca-central-1.amazonaws.com/superset:latest"
- linuxParameters = {
- capabilities = {
- add = []
- drop = [
- "ALL",
]
}
}
- logConfiguration = {
- logDriver = "awslogs"
- options = {
- awslogs-group = "/aws/ecs/superset/celery-beat"
- awslogs-region = "ca-central-1"
- awslogs-stream-prefix = "task"
}
}
- mountPoints = [
- {
- containerPath = "/otel-auto-instrumentation-python"
- readOnly = false
- sourceVolume = "opentelemetry-auto-instrumentation"
},
]
- name = "celery-beat"
- portMappings = [
- {
- containerPort = 8088
- hostPort = 8088
- protocol = "tcp"
},
]
- readonlyRootFilesystem = false
- secrets = [
- {
- name = "SLACK_API_TOKEN"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/slack_api_token"
},
- {
- name = "SMTP_PASSWORD"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_password"
},
- {
- name = "SMTP_USER"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_user"
},
- {
- name = "SUPERSET_DATABASE_HOST"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_host"
},
- {
- name = "SUPERSET_DATABASE_PASSWORD"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_password"
},
- {
- name = "SUPERSET_DATABASE_USER"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_username"
},
- {
- name = "SUPERSET_SECRET_KEY"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_secret_key"
},
]
- systemControls = []
- volumesFrom = []
},
- {
- environment = []
- essential = true
- image = "public.ecr.aws/cloudwatch-agent/cloudwatch-agent:1.300062.0b1304-arm64@sha256:9a790d0f904f15f284c03aaa2a5281244b5c4b71090577f342ed51d13a1eda22"
- logConfiguration = {
- logDriver = "awslogs"
- options = {
- awslogs-create-group = "true"
- awslogs-group = "/ecs/ecs-cwagent"
- awslogs-region = "ca-central-1"
- awslogs-stream-prefix = "ecs"
}
}
- mountPoints = []
- name = "ecs-cwagent"
- portMappings = []
- secrets = [
- {
- name = "CW_CONFIG_CONTENT"
- valueFrom = "arn:aws:ssm:ca-central-1:257394494478:parameter/ecs-cwagent"
},
]
- systemControls = []
- volumesFrom = []
},
- {
- command = [
- "cp",
- "-a",
- "/autoinstrumentation/.",
- "/otel-auto-instrumentation-python",
]
- environment = []
- essential = false
- image = "public.ecr.aws/aws-observability/adot-autoinstrumentation-python:v0.14.0@sha256:cf4cdd456e0b56065f5def48e39a445fdf8a0af5e0bf7d0c1f7385149147c17d"
- mountPoints = [
- {
- containerPath = "/otel-auto-instrumentation-python"
- readOnly = false
- sourceVolume = "opentelemetry-auto-instrumentation"
},
]
- name = "init"
- portMappings = []
- systemControls = []
- volumesFrom = []
},
]
) -> (known after apply) # forces replacement
~ enable_fault_injection = false -> (known after apply)
~ id = "celery-beat" -> (known after apply)
~ revision = 117 -> (known after apply)
tags = {
"CostCentre" = "cds-superset-staging"
"Terraform" = "true"
}
# (13 unchanged attributes hidden)
- volume {
- configure_at_launch = false -> null
- name = "opentelemetry-auto-instrumentation" -> null
# (1 unchanged attribute hidden)
}
+ volume {
+ configure_at_launch = (known after apply)
+ name = "opentelemetry-auto-instrumentation"
# (1 unchanged attribute hidden)
}
# (1 unchanged block hidden)
}
# module.celery_beat_ecs.aws_iam_policy.this_task_exec will be updated in-place
~ resource "aws_iam_policy" "this_task_exec" {
id = "arn:aws:iam::257394494478:policy/celery-beat_ecs_task_exec_policy"
name = "celery-beat_ecs_task_exec_policy"
~ policy = jsonencode(
{
- Statement = [
- {
- Action = [
- "ecr:GetDownloadUrlForLayer",
- "ecr:GetAuthorizationToken",
- "ecr:BatchGetImage",
- "ecr:BatchCheckLayerAvailability",
]
- Effect = "Allow"
- Resource = "*"
},
- {
- Action = "logs:DescribeLogGroups"
- Effect = "Allow"
- Resource = "*"
},
- {
- Action = [
- "logs:PutLogEvents",
- "logs:DescribeLogStreams",
- "logs:CreateLogStream",
]
- Effect = "Allow"
- Resource = "arn:aws:logs:ca-central-1:257394494478:log-group:/aws/ecs/superset/celery-beat:*"
},
- {
- Action = [
- "ssm:GetParameters",
- "ssm:GetParameter",
]
- Effect = "Allow"
- Resource = [
- "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_secret_key",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_username",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_password",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/superset_database_host",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_user",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/smtp_password",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/slack_api_token",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/google_oauth_client_secret",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/google_oauth_client_id",
- "arn:aws:ssm:ca-central-1:257394494478:parameter/ecs-cwagent",
]
- Sid = "GetSSMParameters"
},
- {
- Action = [
- "cloudwatch:PutMetricData",
- "ec2:DescribeVolumes",
- "ec2:DescribeTags",
- "logs:PutLogEvents",
- "logs:PutRetentionPolicy",
- "logs:DescribeLogStreams",
- "logs:DescribeLogGroups",
- "logs:CreateLogStream",
- "logs:CreateLogGroup",
- "xray:PutTraceSegments",
- "xray:PutTelemetryRecords",
- "xray:GetSamplingRules",
- "xray:GetSamplingTargets",
- "xray:GetSamplingStatisticSummaries",
]
- Effect = "Allow"
- Resource = "*"
- Sid = "CWACloudWatchServerPermissions"
},
- {
- Action = [
- "ssm:GetParameter",
]
- Effect = "Allow"
- Resource = "arn:aws:ssm:*:*:parameter/AmazonCloudWatch-*"
- Sid = "CWASSMServerPermissions"
},
]
- Version = "2012-10-17"
}
) -> (known after apply)
tags = {
"CostCentre" = "cds-superset-staging"
"Terraform" = "true"
}
# (7 unchanged attributes hidden)
}
# module.celery_worker_ecs.data.aws_ecs_task_definition.this_latest will be read during apply
# (depends on a resource or a module with changes pending)
<= data "aws_ecs_task_definition" "this_latest" {
+ arn ...Show Conftest resultsWARN - plan.json - main - Missing Common Tags: ["aws_athena_data_catalog.data_lake[\"production\"]"]
WARN - plan.json - main - Missing Common Tags: ["aws_athena_data_catalog.data_lake[\"staging\"]"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_metric_alarm.ses_bounce_rate_high"]
WARN - plan.json - main - Missing Common Tags: ["aws_cloudwatch_metric_alarm.ses_complaint_rate_high"]
WARN - plan.json - main - Missing Common Tags: ["aws_elasticache_subnet_group.superset_cache"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_policy.superset_send_email"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_role.superset_waf_logs"]
WARN - plan.json - main - Missing Common Tags: ["aws_iam_user.superset_send_email"]
WARN - plan.json - main - Missing Common Tags: ["aws_kinesis_firehose_delivery_stream.superset_waf_logs"]
WARN - plan.json - main - Missing Common Tags: ["aws_wafv2_regex_pattern_set.label_sizerestrictions_body_excluded_paths"]
WARN - plan.json - main - Missing Common Tags: ["module.sentinel_forwarder.aws_cloudwatch_log_group.sentinel_forwarder_lambda"]
WARN - plan.json - main - Missing Common Tags: ["module.sentinel_forwarder.aws_iam_policy.sentinel_forwarder_lambda"]
WARN - plan.json - main - Missing Common Tags: ["module.sentinel_forwarder.aws_iam_role.sentinel_forwarder_lambda"]
WARN - plan.json - main - Missing Common Tags: ["module.sentinel_forwarder.aws_lambda_function.sentinel_forwarder"]
WARN - plan.json - main - Missing Common Tags: ["module.sentinel_forwarder.aws_ssm_parameter.sentinel_forwarder_auth"]
34 tests, 19 passed, 15 warnings, 0 failures, 0 exceptions
|
Summary
Add the configuration required to embed Superset dashboards in other services. Authentication from the service will be performed with a dedicated Superset service user.
Additionally this updates the Terraform tools setup action to make Trufflehog available for secret scanning.
Related