Access to api 'getDecryptedValue(password)' from scope has been refused
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-02-2024 02:53 AM
Hello all!
We have a password stored in basic_auth_credentials table that is effectively shared by several apps. In the past, we would normally work exclusively in global scope but have since turned to using scoped apps, reason being it's easier to manage a scoped app by opening up in ServiceNow studio and you're presented with the relevant files. Makes it far easier for other developers in the team to make changes - everything is scoped!
Now, there obvious problem with this is some APIs are restricted from app scope. The one I'm having difficulties with is getDecryptedValue.
Essentially, in my scoped app I have a flow script that runs
const credential = new GlideRecord('basic_auth_credentials');
credential.get('name', 'ADO - Pipeline');
const pat = credential.password.getDecryptedValue();
'ADO - Pipeline' is stored in basic_auth_credentials which I presume is globally scoped, and as mentioned it's used by many different apps which currently sit inside global scope. When script is run in app scope, I get this error:
Security restricted: Access to api 'getDecryptedValue(password)' from scope 'x_clpl_ab_csv_ad_g' has been refused due to the api's cross-scope access policy.
I understand what it means but no idea how to make it work.
As an alternative I've used this script which does work
const credential = new GlideRecord('basic_auth_credentials');
credential.get('name', 'ADO - Pipeline');
const pat = new global.ScopedEncrypter().decrypt(credential.password);
However, it's not recommended to do this as it'll allow app to get any credential whilst all I really need is access to 'ADO - Pipeline'.
Any options available?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
09-02-2024 10:11 PM
In Application Cross-Scope there is no record for my scoped application with requested, but many with allowed. I believe that's because runtime access tracking is set to tracking, which automatically grants access? If set to enforced, it requests.
I suspect, and as you said, getDecryptedValue is an API in global scope that simply can't be accessed from scoped apps leaving something like below running from global scope the only option to use.
const pat = new global.ScopedEncrypter().decrypt(credential.password);
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2024 01:45 PM
Good morning Abelal,
Can you help me understand the risk here? You mentioned ScopedEncrypter().decrypt() is "..not recommended to do this as it'll allow app to get any credential".
Is the concern that maybe a delegated developer is given privileges to make enhancements on an app which is set to "Tracking" and thus he's able to add code to query some forbidden credential record of another app, and uses debugging to steal that?
And maybe if it was set to "Enforced" someone else who is a platform admin would have to intervene?
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
10-24-2024 11:45 PM
Hi @Matt Hernandez,
That is indeed the concern. If application has access to call ScopedEncrypter().decrypt() it can in theory then get access to any credential. I'm by no means an expert in SN so I could very well be wrong here, but based on my limited understand that is a serious security risk.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-19-2024 06:25 PM
Hi @abelal
Have you solved it?
I am facing the same problem. I added Cross-Scope Access and filled the [Target Name] field with [ScopedGlideElement], but it still didn't work.
- Mark as New
- Bookmark
- Subscribe
- Mute
- Subscribe to RSS Feed
- Permalink
- Report Inappropriate Content
12-22-2024 09:36 PM
@JUNXIANW , yes. After raising a ticket with SN support we were advised to use to a different method.
// get record containing credential
var record = new GlideRecord('basic_auth_credentials');
record.get('name', inputs.pattokenname);
// old way
//const pat = credential.password.getDecryptedValue();
//const pat = new global.ScopedEncrypter().decrypt(credential.password);
var provider = new sn_cc.StandardCredentialsProvider();
var credential = provider.getCredentialByID(record.sys_id);
const pat = credential.getAttribute('password');
Hope this helps.