Skip to content

clouds.yaml parser uses user domain as project scope when domains differ #3724

Description

@abnvanand

What happened?

Summary

When user_domain_name/user_domain_id and project_domain_name/project_domain_id point to
different domains in clouds.yaml, authentication either fails with an ErrDomainIDOrDomainName or silently scopes to the wrong project domain. The Python openstackclient handles this correctly but gophercloud's
clouds.Parse() does not.

Root cause

In openstack/config/clouds/clouds.go, ProjectDomainID and ProjectDomainName are coalesced
into AuthOptions.DomainID and AuthOptions.DomainName, but those same fields identify the
user's domain for authentication:

DomainID:   coalesce(..., cloud.AuthInfo.UserDomainID, cloud.AuthInfo.ProjectDomainID, ...),
DomainName: coalesce(..., cloud.AuthInfo.UserDomainName, cloud.AuthInfo.ProjectDomainName, ...),

ToTokenV3ScopeMap then copies these into the project scope (when scoping by project name), so the
project lookup uses the user's domain instead of the project's domain.

Issues

Case 1 --> error (user_domain_name + project_domain_id set to different domains):

clouds:
  mycloud:
    auth:
      auth_url: https://identity.example.com/v3
      username: johndoe
      password: secret
      user_domain_name: userdomain
      project_name: myproject
      project_domain_id: default

DomainName="userdomain" AND DomainID="default" are both non-empty =>
ErrDomainIDOrDomainName:

You must provide exactly one of DomainID or DomainName to authenticate by Username

Case 2 --> silent wrong auth (user_domain_name + project_domain_name pointing to different
domains):

clouds:
  mycloud:
    auth:
      auth_url: https://identity.example.com/v3
      username: johndoe
      password: secret
      user_domain_name: userdomain
      project_name: myproject
      project_domain_name: Default

No parse error, but Keystone receives a token request scoped to project myproject in domain
userdomain instead of Default => 401 Unauthorized.

Expected behaviour

DomainID / DomainName in AuthOptions should carry only the user's domain (from
user_domain_id / user_domain_name). The project domain should be passed to Keystone via the
AuthScope, independent of the user domain, I am not sure how Python openstackclient does it but using same clouds,yaml works with python openstackclient but fails with gophercloud.

Workaround

A workaround with current gophercloud versions is to use project_id instead of project_name in clouds.yaml. Since the UUID is globally unique and identifies the project
without any domain context, bypassing the scoping issue entirely, it works.

Related issues

This is the clouds.yaml counterpart of #3240 and #3440, which report the same problem
in AuthOptionsFromEnv (environment variables).

Version

v2 (current)

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    Fields

    No fields configured for Bug.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions