Open johnboxall opened 4 years ago
Hi @johnboxall, thanks for the kudos and the feedback!
There are two options on how to authenticate with the CLI, the interactive use (a human using the tool) or the automation use (for automated scripts or system to system integrations).
The command sfcc-ci auth:login "${AM_API_CLIENT_KEY}"
runs an Oauth implicit flow (for interactive use) and the (Account Manager) user must authenticate him/herself via the Account Manager login (see sfcc-ci auth:login --help
for details and examples).
The command sfcc-ci client:auth
runs different Oauth flows for automation (see sfcc-ci client:auth --help
for details and examples). In case you want to manage sandboxes for example, you still require an authenticated user (and thus provide Account Manager user credentials) to the command:
sfcc-ci client:auth "${AM_API_CLIENT_KEY}" "${AM_API_CLIENT_PASSWORD}" "${AM_USER}" "${AM_PWD}"
This runs an Oauth resource_owner_password_credentials grant.
sfcc-ci client:auth "${AM_API_CLIENT_KEY}" "${AM_API_CLIENT_PASSWORD}"
without user credentials runs an Oauth client_credentials grant. This can be used for some, but not all (!) of the CLI commands. For example, you make use of the Data APIs on a B2C instance with only a client_credentials grant. However, for other CLI commands (like sandbox management, or Account Manager user and role management) you'd have to provide Account Manager user credentials. This is the also reason why you'e command sfcc-ci sandbox:list
fails.
If you want to automate the sandbox management, it may be a good practice to use a dedicated Account Manager user with only the Sandbox API User role and then to disable 2FA for the Sandbox API User role in your org in Account Manager. This prevents you from being caught with 2FA for your automation user. Other (human) users typically have other roles in Account Manager, which you should have 2FA activated for, thus those user still have to do 2FA if they manage sandboxes via the CLI interactively.
Hope this helps and answers your question!
Thanks @tobiaslohr.
~Given your answer, my understanding is that it is not possible to interact with the Sandbox API using an access_token
provided by sfcc-ci client:auth
.~
My new steps are:
sfcc-ci client:auth "${AM_API_CLIENT_KEY}" "${AM_API_CLIENT_PASSWORD}" "${AM_USER}" "${AM_PWD}"
sfcc-ci sandbox:list
This worked successfully for me. Thank you!
A few notes:
DEBUG=*
flag helpful in observing what was happening, thanks for including it!obtainToken
is not exported from lib/auth
and the exported methods do not accept both sets of credentials and a callback argument. To resolve this you could either export obtainToken
or extend the signature of api.auth
.Super meta feedback: I don't really understand why this API requires an Oauth grant (and more specifically why it would require the user credentials as opposed to the other grant). In future town, it would be nice if I could do what I need to with just an API Key + Secret.
Hey guys,
I have a similar issue. So I authorize my account from CLI but when I try to access sandbox list I see 403 error. Do I need any more rights? I have access to the Control Center with these creds and able to restart sandboxes from there but not from CLI
sfcc-ci client:auth "${AM_API_CLIENT_KEY}" "${AM_API_CLIENT_PASSWORD}" "${AM_USER}" "${AM_PWD}"
Authentication succeeded
sfcc-ci sandbox:list
Error: Retrieving list of sandboxes failed: 403
With Debug mode on I see that response is:
{
"kind": "Status",
"code": 403,
"status": "Failure",
"error": {
"status": "Failure",
"message": "Access is denied",
"reason": "AccessDenied"
}
}
Or does it work only with On-demand sandboxes?
Thanks @tobiaschudalla.
That's a different Tobias ;)
Given your answer, my understanding is that it is not possible to interact with the Sandbox API using an
access_token
provided bysfcc-ci client:auth
.
Not, that is not true and the understanding is wrong. Of course the access_token obtained by the command sfcc-ci client:auth
with API credentials and user credentials can be used to access resources on the Sandbox API server to manage sandboxes.
- Currently, using the JavaScript API, it is not possible to implement the above flow.
obtainToken
is not exported fromlib/auth
and the exported methods do not accept both sets of credentials and a callback argument. To resolve this you could either exportobtainToken
or extend the signature ofapi.auth
.
That is correct. The first and foremost usage for this tool is the CLI. The JavaScript API was never a first class citizen. If there are any JavaScript API enhancements, like the one mentioned, feel free to create an issue.
- Using a user account means we'll need to regularly rotate credentials which is a pain ;P Super meta feedback: I don't really understand why this API requires an Oauth grant (and more specifically why it would require the user credentials as opposed to the other grant). In future town, it would be nice if I could do what I need to with just an API Key + Secret.
Yes, yes and yes. The CLI is only consuming the APIs being available, and implements the authentication flows (Oauth flows) required to do some. Some APIs require only an API client (like some of the OCAPI resources) other APIs (like Sandbox Management or Account Manager APIs for User management) require a user context hence user credentials. The user context is required right now, also for automation use case. For sure, the renewal of the user credentials is odd. The product team is working on enhancements to the APIs to streamline the API access and permissions. That may result in a complete drop of the user context in the future.
I have a similar issue. So I authorize my account from CLI but when I try to access sandbox list I see 403 error. Do I need any more rights? I have access to the Control Center with these creds and able to restart sandboxes from there but not from CLI
@betmakh It is a similar issue, but not the same. The reason why you are seeing this error, is that your Account Manager user does not have the Sandbox API User
role, which is required for management of sandboxes. Please talk to the Account Administrator of the org you want to manage sandboxes for to request this role being granted to your user, execute the CLI commands again, and it will work.
For reference, here is the quick script I ended up with to explore the details of the Sandbox API:
https://gist.github.com/johnboxall/7fd92fb8667314ea4d1628fb5229f162
I am getting the following error, I do not think that there is anything wrong with the four input parameters to sfcc-ci client:auth
command. How can I debug this issue? I have also tried with curl but same error.
{ error_description: 'Resource owner authentication failed', error: 'invalid_grant' }
Finally I could find the problem. Looks like you get this error when 2FA is enabled for Sandbox API automation user and there is no paired 2nd factor device, in the primary organisation of the automation user. In this case, the auth flow is redirected to the "Connect Salesforce Authentocator" page when I tried to login using the Swagger Sandbox API app. Once I disabled the "Sandbox API Role" from the ones which require 2FA (for the primary organisation of automation user), I could get the auth bearer token successfully.
@johnboxall can we close this ticket?
I'm seeing this error again today. Our primary org's 2FA got enabled automatically today by System Process and I cannot disable it!
https://gist.github.com/johnboxall/7fd92fb8667314ea4d1628fb5229f162
Yeah. We are also having a similar issue during fetching of access_token on the AM API - https://account.demandware.com/dw/oauth2/access_token
Response: 401 Unauthorized
{ "error_description": "Client authentication failed", "error": "invalid_client" }
Since we have enabled the Salesforce Authenticator for 2FA/MFA the API calls (below using the curl) fail to fetch the token.
curl -X POST "https://account.demandware.com/dw/oauth2/access_token" -H 'Content-Type: application/x-www-form-urlencoded' --data client_id=${SFCC_OAUTH_CLIENT_ID} --data client_secret=${SFCC_OAUTH_CLIENT_SECRET} --data grant_type=password --data username=${SFCC_OAUTH__USERNAME} --data password=${SFCC_OAUTH_USER_PASSWORD}|jq -r '.access_token'
Nevertheless, the API call using sfcc-ci triggers MFA notifications but the curl does not.
Any clue how we can fix this?
Thanks!
invalid_client
and invalid_token
are different things, the way how the CLI obtains token through the resource owner password credentials grant is documented through the code as you probably know. There is nothing the CLI explicitly makes use of to trigger MFA. Usually this is specified by the MFA method the user / primary org of the user has set.
If the curl is correct or not, I cannot tell. However, this grant type is subject for deprecation in AM and hence we will remove this flow in the CLI. See also https://github.com/SalesforceCommerceCloud/sfcc-ci/wiki/Resource-Owner-Password-Credentials-Authentication-Failure.
As a consequence, I recommend to not use a service user for your use case anymore, but rather switch to a pure client_credentials grant.
I get the same error when running client:auth with just the api client id and api client secret.
DEBUG=* sfcc-ci client:auth '******' '******'
[DEBUG] Configuration loaded from /Users/****/dw.json
[DEBUG] Authorize via Oauth client_credentials grant
[DEBUG] Doing auth request, payload: {"grant_type":"client_credentials"}
{
request: {
debugId: 1,
uri: 'https://account.demandware.com/dw/oauth2/access_token',
method: 'POST',
headers: {
host: 'account.demandware.com',
'content-type': 'application/x-www-form-urlencoded',
authorization: 'Basic *********',
accept: 'application/json',
'content-length': 29
},
body: 'grant_type=client_credentials'
}
}
{
response: {
debugId: 1,
headers: {
'cache-control': 'no-store',
pragma: 'no-cache',
'www-authenticate': 'Basic realm="/"',
'content-type': 'application/json;charset=UTF-8',
'content-length': '77',
date: 'Wed, 26 Apr 2023 13:25:04 GMT',
'referrer-policy': 'strict-origin-when-cross-origin',
'strict-transport-security': 'max-age=15724800; includeSubDomains',
'x-content-type-options': 'nosniff',
'x-frame-options': 'SAMEORIGIN',
vary: 'Accept-Encoding',
'set-cookie': [Array],
server: 'envoy',
connection: 'close'
},
statusCode: 401,
body: {
error_description: 'Client authentication failed',
error: 'invalid_client'
}
}
}
Error: Authentication failed: Client authentication failed
@esmiralha I think you've solved this already as part of https://sfcc-unofficial.slack.com/archives/CAUFG3SHF/p1682597925151959. The credentials passed in were wrong / got mangled (since not escaped properly), as a result the authentication failed.
Hey folks,
Thanks so much for this great tool!
I'm scripting management of our on-demand instances and having trouble using the
access_token
returned bysfcc-ci auth:client
to do it.As I understand it, to allow my script to manage our On Demand instances, I must:
So, following those steps, I first use my API Client to get an
access_token
:Which succeeds returning:
Then I try to list the sandboxes:
Which fails with the following error:
🤔
I should note that if I try the same flow using
auth:login
rather thanauth:client
, things work:This flow wouldn't work however as the intention is to just run a script, not have someone click buttons to auth things :)
Any ideas?
Thanks so much.