How to satisfy a custom Authorization Right?

I’m implementing a custom Authorization right with the following rule:

<key>authenticate-user</key>
<true/>
<key>allow-root</key>
<true/>
<key>class</key>
<string>user</string>
<key>group</key>
<string>admin</string>

The currently logged-in user is a standard user, and I’ve created a hidden admin account, e.g. _hiddenadmin, which has UID≠0 but belongs to the admin group.

From my Authorization Plug-in, I would like to programmatically satisfy this right using _hiddenadmin’s credentials, even though _hiddenadmin is not the logged-in user.

My question:

Is there a way to programmatically satisfy an authenticate-user right from an Authorization Plug-in using credentials of another (non-session) user?

Answered by DTS Engineer in 846945022

Thanks for the clarification.

Can a plug-in participating in a rule chain short-circuit or fulfill an authenticate-user condition on behalf of the system?

No.

I was originally confused by your question because I thought that security credentials might be in play (see QA1277 Security Credentials). However, that’s only relevant if you complete the evaluation, and you’re asking about the behaviour in the middle of the custom.test evaluation. In that context your mechanism, running in the context of custom.test.plugin, has no control over the user targeted by custom.test.authenticate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

We’re missing some vital info here. In general, an authorisation plug-in only runs when it’s included in a mechanisms array, but you’ve not given us any info about which mechanisms array it’s included in.

Having said that, I think the immediate answer to this question:

Is there a way to programmatically satisfy an authenticate-user right from an Authorization Plug-in using credentials of another (non-session) user?

is simply “No.” That’s not how Authorization Services works. If you can explain more about your overall goal, I might be able to offer an alternative path forward.

ps You tagged your thread with Authentication Services, but your question is about Authorization Services. Those are very different APIs, so I removed that tag.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for your reply and insight.

To clarify the setup:

I’ve defined a custom right custom.test as follows:

	<string>rule</string>
	<key>rule</key>
	<array>
		<string>custom.test.plugin</string>
		<string>custom.test.authenticate</string>
	</array>

Where:

custom.test.plugin is defined as:

	<string>evaluate-mechanisms</string>
	<key>mechanisms</key>
	<array>
		<string>AuthorizationPlugin:elevate-privileges,privileged</string>
	</array>

custom.test.authenticate is defined as:

<key>authenticate-user</key>
<true/>
<key>allow-root</key>
<true/>
<key>class</key>
<string>user</string>
<key>group</key>
<string>admin</string>

My Authorization Plug-in is loaded correctly, and the mechanism elevate-privileges is invoked as expected.

My question is: When the system evaluates the right custom.test, is it possible for my plug-in (inside the elevate-privileges mechanism) to programmatically satisfy the custom.test.authenticate rule — for example, by validating the credentials of another admin user?

Or more directly: Can a plug-in participating in a rule chain short-circuit or fulfill an authenticate-user condition on behalf of the system?

Appreciate your help and any guidance you can provide.

Thanks for the clarification.

Can a plug-in participating in a rule chain short-circuit or fulfill an authenticate-user condition on behalf of the system?

No.

I was originally confused by your question because I thought that security credentials might be in play (see QA1277 Security Credentials). However, that’s only relevant if you complete the evaluation, and you’re asking about the behaviour in the middle of the custom.test evaluation. In that context your mechanism, running in the context of custom.test.plugin, has no control over the user targeted by custom.test.authenticate.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

Thank you for the clarification — that makes sense now.

Given that authenticate-user cannot be short-circuited mid-evaluation by a custom plug-in, I’m now interested in understanding how security credentials can be used to fulfill such rights after completing evaluation (as you mentioned in relation to QA1277).

Could you clarify:

  • Under what circumstances can a security credential be created and used to satisfy a right like authenticate-user?
  • Can I programmatically install a credential (e.g., for an admin user who authenticated earlier), so that future calls to AuthorizationCopyRights() succeed without prompting again?
  • Would this approach work across multiple invocations of the same custom rule (e.g., custom.test)?

If you have any example of how to set or retrieve a credential from within a plug-in or client context, that would be immensely helpful.

Thanks again!

I’m not sure I can properly help you with this, because I’m not confident I understand QA1277, which is problematic because I originally wrote it! Honestly, I’m not sure I fully understood it back then either )-:

Regarding your issue, my understanding is that these credentials are generated on successful authentication. However, I’ve never looked into the exact point that generates them, that is, are they generated by the act of successfully gaining a right, or by successfully running a rule, or by the builtin:authenticate method.

You can almost certainly work this out by looking at the code for the authorisation engine in Darwin. A good place to start would be here [1].

WARNING You have to be careful when digging into Darwin. It’s full of implementation details, and encoding such implementation details in your product is not the path to long-term binary compatibility. However, in this case I think it’s reasonable. Authorisation plug-in development is already a field full of compatibility pitfalls.

If you’re on the fence as to whether it’s reasonable to rely on a specific implementation detail, post a summary here and I’ll wade in.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] And, gosh, that code is much easier to read than it was the last time I dug into this stuff.

How to satisfy a custom Authorization Right?
 
 
Q