Scopes Not Returned w/ Client Credential Flow

Yes, you have to use application permissions.

Scopes aka delegated permissions only apply when a user is involved in the login process. They allow you to act on behalf of a user.

Application permissions are sort of roles given to the application itself. They only apply when doing client credentials authentication, where no user is involved. You can define application permissions on the app via the Manifest in the app registration. These can then be assigned to the client application. When getting the token, you must use .default because you cannot change your app permissions dynamically. You always get what has been granted already. In the token the permissions will be in a roles claim.

Can I define custom scope(s) and have them returned when using the client credential flow in Azure AD?

No, but you can define application permission(s) via the manifest (definitely not as nice as the UI for delegated scopes) and have them returned via the client credential flow:

manifest config screenshot

Then you can provide the client app permission:

client permission grant screenshot

Now when requesting a token with a scope of api://web-api-client-credential-flow/.default the "scopes" are returned in the roles claim. Sample JWT

jwt screenshot of roles