Cloud Secret Manager Integration Read

version 2.18

Organizations using cloud platforms need a way to pull secrets directly from their cloud provider’s secret management service at runtime, avoiding credential duplication and leveraging existing rotation policies. This feature adds native integrations with AWS Secrets Manager and Azure Key Vault as Enterprise-only capabilities.

Enterprise

  • AWS Secrets Manager integration — pull secrets at runtime from AWS Secrets Manager using IAM roles, access keys, or assumed roles. Supports JSON-structured secrets with field extraction and automatic rotation. (#2248)
  • Azure Key Vault integration — pull secrets at runtime from Azure Key Vault using managed identity or service principal authentication. Supports secrets, keys, and certificates with automatic rotation. (#2248, #3170)
  • Secret Caching — reduce API calls to cloud providers by caching resolved secrets in memory.

Persistent Repository Cache

version 2.18

Currently, Semaphore clones (or pulls) the repository into a separate directory for every task template, which can be slow for large repositories and wastes disk I/O. This feature adds a per-repository flag that switches to a shared, persistent clone that is updated periodically in the background — similar to how AWX handles project updates. When enabled, all templates that reference the repository share a single working copy (the same model already used for local repositories in Semaphore), and individual task runs no longer trigger a clone or pull.

Community

  • “Cache Repository” flag on Repository settings — add a toggle to each repository that, when enabled, keeps a single persistent clone instead of cloning per task run. The clone is shared across all templates that use the repository, matching the behavior that local repositories already have. (#1212)
  • Background periodic sync — when the cache flag is enabled, pull updates on a configurable interval (e.g., every 5 minutes) in a background worker rather than at task start time, so tasks always launch instantly against a recent checkout.
  • Manual sync action — provide a “Sync Now” button in the repository UI and a corresponding API endpoint to trigger an immediate pull outside the periodic schedule.
  • Force-push / history rewrite resilience — handle upstream force-pushes gracefully (e.g., git fetch --all && git reset --hard origin/<branch>) instead of failing on a normal pull. (#800)
  • Dirty working tree recovery — automatically detect and clean a dirty working tree (e.g., leftover .retry files) before pulling, preventing “local changes” errors. (#308)
  • Stale clone cleanup — garbage-collect cached clones for repositories that have been deleted or whose URL has changed, reclaiming disk space. (#1497, #2679)
  • Sync status visibility — show the last-sync timestamp and status (success/failure) on the repository detail page so users know how fresh the working copy is.
  • Per-repository sync schedule — allow overriding the global sync interval on individual repositories (e.g., high-churn repos every minute, stable repos every hour).

Multiple Variable Groups per Template

version 2.18

Semaphore currently allows attaching a single Variable Group (Environment) to each task template. This forces users to duplicate variables across groups when multiple templates share common settings, or to create monolithic Variable Groups that contain everything. This feature enables composing multiple Variable Groups per template and fixes the numerous bugs in variable handling — serialization, precedence, propagation, and survey variable lifecycle.

Community

  • Multi-environment composition — allow attaching multiple Variable Groups to a single task template so that shared variable sets (e.g., common defaults, per-region overrides) can be composed and reused across templates. (#2612)
  • Clone Variable Groups — add a clone action so environments that differ by only a few values can be set up without recreating all fields from scratch. (#3295)
  • Reusable survey variable sets — decouple survey variables from task templates into standalone assignable objects, avoiding per-template duplication. (#2212)
  • Fix extra-vars JSON serialization — serialize complex extra-vars as proper JSON instead of Go map strings, fixing jsondecode failures in Terraform/OpenTofu. (#3748, #1644, #2619)
  • Fix survey variable precedence — resolve silent override when the same variable name exists in both Environment extra-vars and survey; define clear precedence or raise an error. (#3108)
  • Fix empty/optional survey variable handling — ensure optional survey variables are consistently omitted or passed as empty strings, not randomly mixed. (#2182)
  • Survey defaults for scheduled tasks — allow specifying default values for survey variables when scheduling tasks, so automated runs do not fail on required prompts. (#2244)
  • Pass survey variables as environment variables for bash tasks — expose survey variables as OS environment variables instead of CLI arguments for shell-type tasks. (#2433)
  • Pass survey variables during Tofu/Terraform init — forward survey variables to the init phase, not just plan/apply, to support variable-driven backend configs. (#2554)
  • Jinja2 references in Extra CLI Arguments — allow referencing survey and environment variables in the Extra CLI Arguments field using template syntax (e.g., -l {{ hosts }}). (#1053)
  • Environment variables in run preparation — make environment variables available during the preparation phase (e.g., galaxy install, Git role auth) not just during task execution. (#3178)
  • Load extra-vars from repository file — support loading extra-vars from a JSON/YAML file in the repository instead of inline in the UI, enabling GitOps workflows. (#2343)
  • Override environment at runtime via API — allow passing a different Variable Group when launching a task via API. (#1367, #3291)

Pro

  • Complex survey variable types — support dynamic list-of-objects survey variables (e.g., VLAN configurations) passed as structured JSON arrays. (#3557)
  • Per-schedule variable overrides — attach custom variable values to scheduled jobs so the same template can run on different schedules with different parameters. (#2378)
  • Dynamic variable values from user context — auto-populate variables with the logged-in user’s identity (e.g., {{ current_user }}). (#2524, #909)

Enterprise

  • Mark variables as private — add a “private” flag on variables that prevents values from appearing in run logs, task history, and API responses. (#2887)
  • Restrict environment variable visibility — limit Variable Group contents to admin roles only, preventing credential exposure in shared project templates. (#1126)
  • Build-level variable snapshots — snapshot variable values at task execution time so re-runs use the original values, not current ones. (#1097)

User-Owned Secrets

version 2.18

Semaphore’s key store is currently shared across all project members. Any user with project access can use (and in some cases view) all stored credentials. This creates security concerns in multi-user environments where team members should only have access to their own credentials. Additionally, the key store has multiple bugs around encryption, secret updates, and reference integrity, and lacks integration with external secret management systems.

Community

  • Personal keystore — provide a per-user keystore so that personal credentials (SSH keys, sudo passwords) are isolated from other project members and not shared through the project-level key store. (#1483, #1373)
  • Fix secret update behavior — resolve the issue where editing a secret environment variable appears to succeed but the value is not actually persisted. (#2546)
  • Hide secrets from process list — stop passing secret extra-vars via command-line arguments visible in the OS process list; use a secure mechanism (e.g., temp files, stdin). (#3219)
  • SSH certificate support in key store — allow storing SSH certificates alongside SSH keys for certificate-based authentication workflows. (#3171)
  • Show SSH public key — display the public key portion of stored SSH keys in the key store UI for convenience. (#1643)
  • Docker secrets support — support _FILE env var pattern (e.g., POSTGRES_PASSWORD_FILE) so Docker/Kubernetes secrets can be mounted and read instead of passing via environment variables. (#1268)
  • Fix encryption key handling in Docker — ensure SEMAPHORE_ACCESS_KEY_ENCRYPTION env var is respected and does not get overwritten with a random key on container restart. (#2228, #3068, #3204)
  • Fix key store rename breaking references — resolve the issue where renaming a key store entry breaks all linked inventories and templates. (#3188)
  • Fix vault password API — allow setting and updating Ansible Vault passwords via REST API without duplicate key constraint errors. (#3413, #2773)

Pro

  • External secret store integration — pull secrets at runtime from HashiCorp Vault, Azure Key Vault, AWS KMS, or Bitwarden instead of storing them in Semaphore’s database. (#2248, #658)

Enterprise

  • Global access keys — share key store entries across projects without duplication, with centralized management and cross-project linking. (#110)
  • Secret access audit trail — log all access and usage of key store entries and secret variables for compliance and forensics.

Credentials for requirements.yml Read

version 2.18

Ansible playbooks frequently declare private roles and collections in requirements.yml that live in private Git repositories. Semaphore currently has no first-class way to authenticate ansible-galaxy install against those repositories — users resort to embedding tokens in URLs, baking SSH keys into runner images, or maintaining custom preparation scripts. This feature lets users attach one or more key-store credentials to a task template (or playbook run) and have them used automatically during the preparation phase when roles and collections are resolved.

Community

  • Attach credentials to a playbook run — allow selecting one or more key-store entries (SSH key, Git token, username/password) on a task template that are applied during ansible-galaxy install so private roles and collections listed in requirements.yml can be pulled from private Git repositories. (#3677, #3708, #897)
  • Per-host-pattern credential mapping — when multiple credentials are attached, map them to hostname patterns (e.g., github.com, gitlab.internal) so each private source uses the correct key or token without collisions. (#3677)
  • Fix env var propagation to galaxy install stage — ensure environment variables (including secret ones) are exported during ansible-galaxy install, not only during playbook execution, so token-based auth works for requirements.yml. (#2966, #3178)
  • Per-playbook requirements file — allow overriding the default roles/requirements.yml / collections/requirements.yml path at the template level for projects that group multiple playbooks with different dependency sets. (#1366)
  • Custom ansible-galaxy CLI arguments — expose a field for extra arguments passed to ansible-galaxy install (e.g., --ignore-certs, --force, custom server), covering air-gapped and internal Galaxy mirror setups. (#2348)

LDAP and OpenID Group Mapping

version 2.19

Semaphore supports LDAP and OpenID Connect (OIDC) for authentication, but the integration stops at login — there is no automatic role or project assignment based on identity provider group memberships. Every OIDC/LDAP user must be manually assigned to projects and roles after first login. Additionally, there are multiple bugs in OIDC redirect handling, claim parsing, and LDAP configuration that make the authentication experience unreliable.

Community

  • Restrict OIDC login by claim — allow only users with specific claim values (e.g., required group membership or email domain) to log in. (#2626, #2938)
  • SSO auto-login — bypass the login screen and redirect directly to the OIDC/SSO provider, with a failsafe URL for recovery if SSO is down. (#2548, #2899)
  • OIDC PKCE support — add Proof Key for Code Exchange to the OIDC authorization code flow as recommended by RFC 9700. (#3072)
  • OIDC environment variable configuration — allow configuring OIDC providers via environment variables instead of only config file, simplifying secrets management in containers. (#2528, #3120)
  • Fix OIDC redirect with web_host/web_root — resolve 404 errors after OIDC login when web_host is empty or web_root is set to a subpath. (#2681, #1524, #2532, #3121)
  • Fix OIDC claim handling — resolve issues with username_claim being ignored, email claim not being recognized, and client_secret_file producing malformed requests. (#1731, #2818, #3122)
  • Fix LDAP claim expressions — resolve broken template expressions in LDAP mapping (e.g., mail | {{ .username }}@domain.com resolving to <no value>). (#3127)
  • Fix LDAP username assignment — ensure LDAP users get their actual LDAP username instead of a randomly generated string. (#3688)
  • LDAP local auth fallback — allow local admin accounts to still log in when LDAP is enabled, preventing lockout if the LDAP server is down. (#1363)
  • LDAP debug logging — add useful log output for LDAP authentication failures to make troubleshooting possible. (#2932)
  • OIDC/LDAP user-to-local account linking — allow converting or linking existing local accounts to external identity providers without creating duplicates. (#3339)
  • OIDC provider logout — end the IdP session (e.g., Keycloak) when logging out of Semaphore, enabling proper account switching. (#1496)

Pro

  • Sync LDAP credentials to access keys — optionally auto-update the access key password when the LDAP password changes on login, keeping Ansible credentials in sync. (#3696)

Enterprise

  • OIDC group-to-role mapping — auto-assign Semaphore roles and project memberships based on OIDC claims (e.g., groups claim), eliminating manual user setup after first login. (#1499, #2483)
  • LDAP group-to-role mapping — map Active Directory / LDAP groups to Semaphore roles, including admin role assignment via group membership. (#3226, #1316)
  • Full RBAC with LDAP/OIDC integration — implement granular role-based access control (global admin, project admin, project user, read-only) with automatic role assignment from external identity provider groups. (#891)
  • Pluggable authentication architecture — abstract authentication into a provider interface to support multiple auth backends and simplify adding new providers. (#465, #1820)
  • Fix user deletion leaving orphan data — ensure deleting a user cleans up project__user mappings to prevent Team view crashes. (#3514)

Flexible Notification System

version 2.19

The current notification system in Semaphore UI is configured exclusively through config.json, supports a limited set of channels (Email, Telegram, Slack, MS Teams), and operates at the global level with minimal per-project customization. This feature redesigns notifications from the ground up to be UI-managed, extensible, and configurable at project and template granularity.

Community

  • Extensible channel architecture — define a common interface for notification channels with per-channel implementations, making it straightforward to add new channels without modifying core logic. Consider adopting a universal notification library (e.g., nikoksr/notify) or gateway (e.g., Apprise) to cover many providers at once. (#2325, #1290)
  • UI-managed notification configuration — move notification setup from config files into the Web UI with per-project and per-template granularity, supporting multiple instances of the same channel type. (#3387, #1821, #3588)
  • Template-based message customization — support user-defined message templates stored as files on disk rather than in the database.
  • Per-project channel selection — allow users to configure which notification channels are active on a per-project basis through project settings. (#3588)
  • Outbound webhook events — define event types (START, SUCCESS, FAILURE) and allow creating webhook templates per project with configurable URL, headers, and HMAC authentication. (#1825, #2594, #3066)
  • New notification channels — add support for Discord (#2924), Ntfy (#3383), Google Chat (#1148), Rocket.Chat (#1091), and Pushover (#2594).
  • “Fixed” notifications — send a notification on the first successful run after a failure, similar to GitLab CI recovery alerts. (#3380)
  • Disable all notifications per template — add a “Disable All Notifications” option alongside the existing “Disable Successful Notifications” checkbox. (#3724)
  • Email on success — include email in the success notification path (currently only Telegram/Slack/MS Teams fire on success). (#3503)
  • Fix task URL in notifications — ensure all channels (email, Slack, MS Teams) receive a fully qualified task URL with scheme and host, not a relative path. (#2097, #2311, #3292)
  • Fix email delivery issues — resolve SMTP port 465 (implicit TLS) support, auth-before-TLS ordering, and Date header formatting. (#2201, #2971, #3542, #3209)
  • Telegram thread/topic support — allow sending notifications to specific Telegram group threads via message_thread_id, configurable per-project and per-template. (#3493, #1456)
  • Slack template improvements — expose top-level fields (title, text, color) for Slack Workflow Builder compatibility. (#2607)
  • Alert proxy support — allow configuring an HTTP proxy for outbound notification requests without requiring a system-wide proxy. (#1484)

Pro

  • Pro-only notification channels — support specific notification channels exclusively in the Pro plan.
  • Long-running task alerts — trigger a notification when a task exceeds a configurable duration threshold. (#1393)

Enterprise

  • Audit log for notifications — maintain a searchable log of all sent notifications with delivery status, timestamps, and recipient details. Improve error logging to include recipient context on failures. (#3410)
  • Integration with incident management platforms — native integrations with PagerDuty, Opsgenie, and ServiceNow for automatic incident creation and lifecycle tracking.
  • Role-based notification access control — restrict who can configure notification rules and channels based on organizational roles and permissions.

Multiple Inventories per Template

version 2.19

Ansible CLI natively supports passing multiple -i arguments to compose inventories (e.g., ansible-playbook -i common_vars.yml -i staging_hosts.yml). Semaphore currently restricts each task template to a single inventory, forcing users into workarounds such as inventory scripts, merged files, or extra environment variables. This feature lifts that restriction and addresses the broader set of inventory management gaps.

Community

  • Multi-inventory support — allow attaching multiple inventories to a single task template, passed as sequential -i arguments to Ansible (e.g., ansible-playbook -i common_vars.yml -i staging_hosts.yml). Resolves the limitation of one inventory per template. (#2093)
  • Optional inventory field — make the inventory field on templates optional for cases where ansible.cfg already specifies the inventory source. (#1574)
  • URL/HTTP inventory source — support fetching inventory from a remote URL or API endpoint, essential for hosted/SaaS environments without filesystem access. (#1924)
  • Runtime inventory selection — allow users to select an inventory at task launch time via a dropdown, replacing the current free-text workaround. (#1354)
  • Fix scheduled task inventory persistence — ensure the inventory selected in a schedule dialog is saved and used at execution time instead of falling back to the template default. (#3566, #3293)
  • Fix project export/restore losing inventory repository link — inventory-to-repository associations are dropped during project export and not restored on import. (#3369, #3177)
  • Pass environment variables to dynamic inventory — ensure container/host environment variables are available to dynamic inventory scripts and plugins (e.g., Python scripts, microsoft.ad.ldap). (#2724, #2783)
  • Fix git-based inventory authentication — use repository credentials when fetching remote branches for inventory, fixing unauthenticated access attempts. (#3539)
  • Per-host credential overrides — stop overriding per-host ansible_user and connection variables defined in inventory with global --extra-vars. Allow multi-user inventory patterns. (#1464, #1621)
  • View inventory content in UI — display file-based and dynamic inventory contents in the UI for inspection and debugging, with a link to the source file in the external repository. (#3169, #1555, #3543)
  • Expose inventory name in task context — make the inventory name available in semaphore_vars or as an environment variable so playbooks can reference which inventory is active. (#1580)

Pro

  • Inventory-to-runner affinity — associate inventory hosts with runner tags so tasks are dispatched only to runners that have network access to the target hosts, avoiding failures in multi-network environments. (#3322)
  • Multiple SSH keys per inventory — allow assigning multiple key-store entries to a single inventory for fleets where each host uses a unique SSH key. (#3336)
  • Hypervisor inventory integration — native integration with hypervisor APIs (VMware, Proxmox) to auto-generate and refresh dynamic inventories. (#2709)
  • Host group management API — provide an API to add/remove hosts from inventory groups without rewriting the entire inventory payload. (#1560)

Enterprise

  • Restrict allowed inventories per template — when a template has “ask for inventory” enabled, limit the selectable inventories to an administrator-defined allowlist, preventing accidental targeting of wrong environments. (#3587)
  • Central host registry — provide a shared host management layer so that host changes (e.g., hostname or IP updates) propagate to all inventories referencing that host without manual edits. (#564)
  • Host fact storage and visualization — store Ansible facts per host and display state before/after task runs with diff and history capabilities. (#930)

Workflows

version 2.21

Semaphore currently treats each task template as an independent unit — there is no built-in way to chain multiple templates into a multi-step execution pipeline. This feature introduces Workflows — directed acyclic graphs (DAGs) of task templates that execute with conditional branching, variable passing between steps, and optional human approval gates. The design draws from AWX Workflow Job Templates, Rundeck job workflows, and Jenkins/GitLab CI pipeline concepts.

Community

  • Workflow templates — introduce a new top-level entity that defines a DAG of task template nodes connected by directed edges with conditions (on_success, on_failure, always), enabling multi-step automation pipelines within a project. (#3182, #2334, #1383, #836)
  • Workflow execution engine — execute workflow nodes in topological order, respecting edge conditions and running independent branches in parallel, with ALL-convergence for nodes that have multiple parents. (#2281, #3088)
  • Workflow run dashboard — provide a unified view of workflow execution showing the DAG graph with per-node status (pending, running, succeeded, failed, skipped), clickable node logs, and overall timing.
  • Variable passing between nodes — allow task templates to emit output variables (via a well-known file or Ansible set_stats) that are automatically injected as extra variables into downstream nodes. (#3182)
  • Workflow scheduling and API triggers — support cron scheduling, API-triggered runs, and webhook triggers for workflows, with optional survey variables at the workflow level. (#3088)

Pro

  • Visual workflow editor — drag-and-drop graphical editor for designing workflows in the UI, with real-time DAG validation, node positioning, and condition selectors on edges.
  • Per-node overrides — override a template’s inventory, credentials, variable groups, or CLI arguments at the workflow node level, enabling reuse of the same template across different environments within a single workflow.
  • Approval gates — pause workflow execution at designated points to wait for human approval, with configurable timeouts, notification to approvers, and approve/reject actions from the UI or API.

Enterprise

  • Workflow RBAC — fine-grained permissions for creating, editing, executing, and approving workflows, with role-based approval gate assignment and audit logging.
  • Cross-project workflows — reference task templates from other projects in a workflow, enabling organization-wide automation pipelines that span infrastructure, application, and monitoring projects.
  • Workflow versioning and rollback — maintain a version history of workflow definitions with diffs, restore previous versions, and record which version was used for each run.