Why team rewrites in one login policy don't affect other login policies

Last updated: November 3, 2026

Overview

Spacelift's login policy allows you to rewrite the list of teams received from your identity provider (IdP) using the team rule. However, if you have multiple login policies, you may notice that team rewrites defined in one policy are not visible to another. This article explains why this happens and how to resolve it.

How multiple login policies are evaluated

Each login policy is evaluated separately against the same original input from the IdP. The results are then combined afterwards. This means:

  • Inside a single login policy: input.session.teams always holds the original IdP teams. To reference rewritten teams within the same policy, use the team rule directly rather than input.session.teams.

  • Across multiple login policies: Rules in one policy cannot see the team values produced by another policy. Each policy only has access to the original IdP input and its own locally defined rules.

Spacelift does not load multiple login policies as a single OPA module. Because of this, a team rewrite defined in one login policy will not be reflected in input.session.teams when a second login policy is evaluated.

Once every attached login policy has been evaluated, their team outputs are combined into a union, not an override. If Policy A's team rule produces {"SoftwareEngineers"} and

Policy B also defines a team rule that produces {"QA"}, the account's final session teams will be {"SoftwareEngineers", "QA"}, the combined set from both, not whichever policy happened to run last. Keep this in mind if more than one of your login policies defines a team rule.

Common symptom

If you have one login policy that rewrites IdP groups (e.g., mapping EngStack-* groups to logical roles like SoftwareEngineers) and a second login policy that uses those logical roles to control access (e.g., to spaces), the second policy will only see the original IdP teams — not the rewritten ones. As a result, the second policy's access rules will silently evaluate against those original teams and produce no matching grants.

Solutions

There are two recommended approaches to resolve this:

  1. Merge all login policies into one file. Combine your team-mapping logic and your access rules into a single login policy. Within that policy, reference the team rule (not input.session.teams) wherever you need to use the rewritten teams.

  2. Combine policies at deploy time. If keeping everything in one source file is not practical, concatenate or bundle the policy files into a single policy before deploying to Spacelift, so Spacelift receives them as one policy.

  3. Duplicate the mapping logic as a helper rule. In the second login policy, replicate the IdP-to-role mapping as a local helper rule (e.g., mapped_teams, not named team) and base your access rules on that helper rule instead.

Spacelift's documentation recommends having only one login policy to avoid unexpected results when multiple policies are merged.

Additional reference

For more details on how the team rule works and how to rewrite teams in a login policy, see the Login Policy documentation and the rewriting-user-teams example policy.