Skip to navigation

Group membership

group_membership "app" {
ensure = "present"
members = ["user1", "user2"]
exclusive = true
}
ParameterDefaultBehavior
grouplabelLocal group whose supplementary membership is managed.
ensure"present"Add listed members when present; remove only listed members when absent.
membersrequiredList of local usernames; duplicates collapse to a set.
exclusivefalseWith present, make the supplementary member list exactly equal to members. Unsupported with absent.

Additive members=[] preserves membership; exclusive members=[] clears the supplementary list. The resource neither creates nor deletes users or groups and leaves memberships in other groups untouched. Primary-group membership stays under user.primary_group; exclusive applies only to explicit supplementary entries, so users with this primary GID retain primary membership. Group administrators and passwords stay unmanaged. Native operations use gpasswd, which updates the local group and gshadow files under shadow-utils locking.

Present membership requires an existing local group and existing local members; remote NSS identities are refused. Absent membership also works after the group or listed users have been removed. Managed group and listed user declarations automatically precede membership, including literal names; present membership cannot refer to managed absent accounts. References such as group.app.name and user.worker.name also retain provenance.

Multiple additive and absent resources may manage disjoint users in the same group. Overlapping member claims are rejected, and an exclusive declaration owns the whole supplementary list. Conflicts with user.groups are rejected too: additive user ownership conflicts when it lists the same group and member; exact user ownership conflicts whenever the membership resource manages that user, or manages the group exclusively. Leave user.groups omitted for those users when delegating their supplementary membership to these resources.

Execution and exports

The shared resource budget is 60 seconds. Mutations are journaled before native execution and verified with fresh inspection. Noop does not write memberships or future intent. Names follow the same local account rules as users and groups. Explicit null is rejected for these policy fields.

Static exports are group, ensure, members, and exclusive, plus common meta.sensitive. Capability: group_membership.shadow.v1.