Allowing a script to add members to a Group without giving it admin access to all Groups?

700 views
Skip to first unread message

Ian Crew

unread,
Mar 1, 2024, 11:24:13 AM3/1/24
to Google Apps Script Community
Hi all:

(Tried searching for this in the archives, and more broadly across the internet, but searching for the term "Groups" doesn't work so well, especially in a Groups-based mailing list like this one. Forgive me if this is an FAQ.)

The subject line pretty much says it all. I'm writing a script that I want to have add members to a single Google Group. How can I allow that script to do that, without giving it full Group Admin permissions to every group? 

I want to avoid giving it admin access because that will turn into a large bunch of security paperwork which I'd just as soon avoid; not to mention the overall security best practice of only granting necessary access, not more.

Thanks!

Ian

Laurie Nason

unread,
Mar 3, 2024, 1:51:01 AM3/3/24
to google-apps-sc...@googlegroups.com
Somebody may be able to correct my understanding, but as far as I know:

In order to add members to groups using a script - you need to be a member of that group with the appropriate permissions (I've done it in a script where I can only do things to groups I am a member of - like adding/removing members) - other groups I can read group information provided I have permission set at the group level - but can't do anything more.

The other way is to look at "Domain-wide delegation" where 
"As an administrator, you can use domain-wide delegation to allow internal and third-party apps to access your users’ Google Workspace data, bypassing end user consent. To do this, you create a service account in the Google Cloud console and delegate domain-wide authority to the account in your Google Admin console. "

However, if you're trying to avoid security paperwork - this won't work either :-(

Laurie




--
You received this message because you are subscribed to the Google Groups "Google Apps Script Community" group.
To unsubscribe from this group and stop receiving emails from it, send an email to google-apps-script-c...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/google-apps-script-community/b158c994-6d5b-4808-9f82-62bb61612d06n%40googlegroups.com.

Ian Crew

unread,
Mar 3, 2024, 12:16:13 PM3/3/24
to google-apps-sc...@googlegroups.com
Thanks Laurie:

I’m still stuck on this—do you have an example of how to do it, perhaps?


I do see addGroupMember() as part of the Admin SDK Directory Service, at https://developers.google.com/apps-script/advanced/admin-sdk-directory#add_group_member, but that service is described as "This API gives administrators of Google Workspace domains (including resellers) the ability to manage devices, groups, users, and other entities in their domains.” (emphasis mine) That’s obviously a whole pile of very high-level access. Even just “groups administrator” is a whole bunch, given how Groups often secure access to other services and data.

But, like I said, running my script as an admin will turn into a whole pile of paperwork with our security team, so I’d really rather not go that route. 

I was hoping that there might be a way to make the (non-administrator) user I’m running the script as an owner or manager of a single group, and that that would give the script the ability to add folks to that group.

Any additional thoughts or code examples would be most appreciated.

Thanks,

Ian

Laurie Nason

unread,
Mar 4, 2024, 12:12:51 AM3/4/24
to google-apps-sc...@googlegroups.com
Hi - sorry, I don't think that you can do anything unless you are an admin member of the group - or you are a domain administrator
The link here to the admin sdk is probably what you are looking for - but again - for security reasons, you'll need to have higher privileges to view groups the current users is not associated with.

Here's my code using the sdk which you have to add to the services in the appscript:

do {
page=AdminDirectory.Groups.list({
domain: GoogleDomain,
maxResults: 100,
pageToken: pageToken
});
var groups=page.groups;
if(groups){
for(var g=0;g<groups.length;g++){
var thisRow=[];
logInfo('getGroups','Getting Group Information: '+ groups[g].email,true,true,2);
//now get the full group information
var myGroup=AdminGroupsSettings.Groups.get(groups[g].email);
//put in direct members count in the first column
thisRow.push(groups[g].directMembersCount);
//loop through headers - starting at second column
for(var h=1;h<groupsSheetHeaders.length;h++){
thisRow.push(myGroup[groupsSheetHeaders[h]]);
}
//push this into the myGroups
myGroups.push(thisRow);
}
} else {
logInfo('getGroups','No Groups Found');
}
//get next page token
pageToken = page.nextPageToken;

} while (pageToken);//end do loop

A couple of notes to explain above:
  • GoogleDomain is a constant with the name of your domain you want to query
  • my own function logInfo just logs the step on another google sheet tab and potentially shows the user what process is happening.
  • groupsSheetHeaders is a list of the field names (column headers on the sheet that I eventually write to) that the function returns that I then push into thisRow which then is ultimately added to myGroups 
  • It's then paging through the tokens as we have a LOT of groups on our domain
function getGroupMembers(groupEmail){
var membersSheet=SpreadsheetApp.getActiveSpreadsheet().getSheetByName(GroupMembersSheetName);
var groupMembersHeaders=membersSheet.getRange(GroupMembersSheetHeaders).getValues()[0];
var myMembers=AdminDirectory.Members.list(groupEmail);
var allMembers=[];
var myRow=[];
//log this
logInfo('getMembers','Getting Members for: '+ groupEmail,true,10);
//get member info
for(var m=0;m<myMembers.members.length;m++){
//clear the row information
myRow=[];
//first col is the group email so push that now
myRow.push(groupEmail);
var curMember=myMembers.members[m];
//loop through headers for this member - start at 1 because of the group email
for(var h=1;h<groupMembersHeaders.length;h++){
myRow.push(curMember[groupMembersHeaders[h]]);
}
//add row to all members
allMembers.push(myRow);
}

return allMembers;
}

Then this function is used to return the information about group members (a couple of named ranges are used to define the headers again)

Hope this helps a bit!


Laurie




Ian Crew

unread,
Mar 4, 2024, 1:11:37 AM3/4/24
to google-apps-sc...@googlegroups.com
OK, I’m confused, sorry:

Are you saying that if I make the user an owner or manager of the Group, I can use AdminDirectory.groups, without giving the script that scope for every group in my domain? That’d be ideal.

Sorry if I’m asking stupid questions!

Thanks!

Ian

Laurie Nason

unread,
Mar 4, 2024, 2:36:10 AM3/4/24
to google-apps-sc...@googlegroups.com
Sorry - no - you can only access groups that you have permission to do so. 
If you are a google admin-  you can potentially use the service to show ALL groups.

Laurie




Ian Crew

unread,
Mar 4, 2024, 10:44:52 AM3/4/24
to google-apps-sc...@googlegroups.com
I feel like I’m being incredibly dense, but I’m still confused. You wrote:

1) "you can only access groups that you have permission to do so”

My interpretation/confusion:  I’m deploying the script as “Execute the app as me”. If the script owner (that the script is running as) is the owner or manager of the Group, doesn’t the script owner have permission to access that group?

2) "If you are a google admin-  you can potentially use the service to show ALL groups.”

My interpretation/confusion: This makes it sound like it’s possible to call “AdminDirectory.Groups” without being an admin? Is that the case? That—not having to have the account that owns and executes the script—is exactly what I’m looking for.

So it sounds like it is indeed possible to do what I want, but you led with “sorry-no”. So I’m really confused….

Thanks,

Ian



Ian Crew

unread,
Mar 4, 2024, 3:57:15 PM3/4/24
to google-apps-sc...@googlegroups.com
I also tried it for myself, based on your second script, and I’m getting the following (this is just a script associated with a Sheet); and the user I’m running it as is a manager of the group in line 2.

As you can see, it falls on line 8 with "GoogleJsonResponseException: API call to directory.members.list failed with error: Not Authorized to access this resource/api"

So maybe I’m indeed out of luck?

Thanks again,

Ian

Screenshot 2024-03-04 at 12.52.53 PM.png

Laurie Nason

unread,
Mar 5, 2024, 11:51:23 PM3/5/24
to google-apps-sc...@googlegroups.com
Sorry for the late reply - it would seem so - if you look at group permissions you'll see this option:
image.png

Depending on the highlighted yellow option - even the group manager may not be able to view the members information. 
Sorry - The security on google (though sometimes a pain) is there for a good reason!


Laurie




Ian Crew

unread,
Mar 6, 2024, 5:10:20 PM3/6/24
to google-apps-sc...@googlegroups.com
Hi Laurie:

Thanks very much for your continued help. The user I’m running the script is a manager of the group, and the group managers can see members, manage members, and see member email addresses (it’s been that way for a long time, none of these are recent changes):

Screenshot 2024-03-06 at 2.08.01 PM.png

PastedGraphic-1.png
PastedGraphic-2.png




On Mar 5, 2024, at 8:51 PM, Laurie Nason <laurie...@thekaustschool.org> wrote:

Sorry for the late reply - it would seem so - if you look at group permissions you'll see this option:
<image.png>

Depending on the highlighted yellow option - even the group manager may not be able to view the members information. 
Sorry - The security on google (though sometimes a pain) is there for a good reason!


Laurie


On Mon, Mar 4, 2024 at 11:57 PM 'Ian Crew' via Google Apps Script Community <google-apps-sc...@googlegroups.com> wrote:
I also tried it for myself, based on your second script, and I’m getting the following (this is just a script associated with a Sheet); and the user I’m running it as is a manager of the group in line 2.

As you can see, it falls on line 8 with "GoogleJsonResponseException: API call to directory.members.list failed with error: Not Authorized to access this resource/api"

So maybe I’m indeed out of luck?

Thanks again,

Ian

Laurie Nason

unread,
Mar 6, 2024, 11:28:35 PM3/6/24
to google-apps-sc...@googlegroups.com
That is seriously strange - did you get prompted to authorise yourself when you first ran the script?
It maybe that needs to happen?

Laurie




Reply all
Reply to author
Forward
0 new messages