Skip to content

CreateSubjectMapping with multiple SubjectSets (OR'd conditions) silently fails to persist #3189

@marythought

Description

@marythought

Description

When using the Go SDK's CreateSubjectMapping with multiple SubjectSets in a single SubjectConditionSetCreate (to create OR'd conditions), the API call returns success but the mappings either don't persist or don't evaluate correctly.

Steps to Reproduce

  1. Create a subject mapping via the Go SDK with 2 SubjectSets:
    sdk.SubjectMapping.CreateSubjectMapping(ctx, &subjectmapping.CreateSubjectMappingRequest{
        AttributeValueId: valueID,
        Actions: []*policy.Action{{Name: "read"}},
        NewSubjectConditionSet: &subjectmapping.SubjectConditionSetCreate{
            SubjectSets: []*policy.SubjectSet{
                // SubjectSet 1: owner
                {ConditionGroups: []*policy.ConditionGroup{{
                    Conditions: []*policy.Condition{{
                        SubjectExternalSelectorValue: ".preferred_username",
                        Operator: policy.SubjectMappingOperatorEnum_SUBJECT_MAPPING_OPERATOR_ENUM_IN,
                        SubjectExternalValues: []string{"alice"},
                    }},
                    BooleanOperator: policy.ConditionBooleanTypeEnum_CONDITION_BOOLEAN_TYPE_ENUM_AND,
                }}},
                // SubjectSet 2: doctor role
                {ConditionGroups: []*policy.ConditionGroup{{
                    Conditions: []*policy.Condition{{
                        SubjectExternalSelectorValue: ".realm_access.roles[]",
                        Operator: policy.SubjectMappingOperatorEnum_SUBJECT_MAPPING_OPERATOR_ENUM_IN,
                        SubjectExternalValues: []string{"opentdf-doctor"},
                    }},
                    BooleanOperator: policy.ConditionBooleanTypeEnum_CONDITION_BOOLEAN_TYPE_ENUM_AND,
                }}},
            },
        },
    })
  2. The call returns no error
  3. ListSubjectMappings via the Go SDK shows the mapping exists
  4. otdfctl policy subject-mappings list shows 0 mappings for this attribute value
  5. Decrypt attempts fail — the mapping doesn't evaluate

Expected Behavior

The mapping should persist and the OR'd condition sets should evaluate (any matching SubjectSet grants access).

Actual Behavior

  • CreateSubjectMapping returns success (no error)
  • Go SDK's ListSubjectMappings returns the mapping
  • otdfctl does not see the mapping
  • Entitlement evaluation returns empty

Workaround

Create separate mappings (one per condition) instead of OR'd SubjectSets in a single mapping. This works reliably:

// Mapping 1: owner
sdk.SubjectMapping.CreateSubjectMapping(ctx, &subjectmapping.CreateSubjectMappingRequest{
    AttributeValueId: valueID,
    NewSubjectConditionSet: &subjectmapping.SubjectConditionSetCreate{
        SubjectSets: []*policy.SubjectSet{{/* owner condition only */}},
    },
})

// Mapping 2: doctor (separate call)
sdk.SubjectMapping.CreateSubjectMapping(ctx, &subjectmapping.CreateSubjectMappingRequest{
    AttributeValueId: valueID,
    NewSubjectConditionSet: &subjectmapping.SubjectConditionSetCreate{
        SubjectSets: []*policy.SubjectSet{{/* doctor condition only */}},
    },
})

Additional Context

  • otdfctl policy subject-mappings create with --subject-condition-set-new containing multiple subject sets DOES work
  • The issue appears to be specific to the Go SDK's gRPC client, not the platform API itself
  • This is a silent failure — no error returned, making it very difficult to debug

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions