- [Update an existing Service Account key](#update-an-existing-service-account-key)
- [Replace all existing Service Account keys](#replace-all-existing-service-account-keys)
- [Delete Service Account keys](#delete-service-account-keys)
- [Upload a Service Account key to a service account with no keys](#upload-a-service-account-key-to-a-service-account-with-no-keys)
- [Display Service Account keys](#display-service-account-keys)
- [Upload a Service Account key to a service account without a valid private key](#upload-a-service-account-key-to-a-service-account-without-a-valid-private-key)
- [Manage Service Account access](#manage-service-account-access)
- [Full Service Account access](#full-service-account-access)
- [Selective Service Account access](#selective-service-account-access)
@@ -394,9 +394,9 @@ gam show projects [[admin] <EmailAddress>] [all|<ProjectIDEntity>]
*`<EmailAddress>` - A Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
Use these options to select projects.
*`all` - All projects accessible by the administrator; this is the default
*`all` - All projects accessible by the administrator
*`current` - The project referenced in `client_secrets.json`
*`gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`
*`gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`; this is the default
*`<ProjectID>` - A Google API project ID
*`filter <String>` - A filter to select projects accessible by the administrator; see the API documentation
*`states all|active|deleterequested` - Limit display to projects based on state; the default is `active`
*`<EmailAddress>` - A Google Workspace admin/GCP project manager; if omitted, you will be prompted for the address
Use these options to select projects.
*`all` - All projects accessible by the administrator; this is the default
*`all` - All projects accessible by the administrator
*`current` - The project referenced in `client_secrets.json`
*`gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`
*`gam` - Projects accessible by the administrator that were created by Gam, i.e, their project ID begins with `gam-project-`; this is the default
*`<ProjectID>` - A Google API project ID
*`filter <String>` - A filter to select projects accessible by the administrator; see the API documentation
*`states all|active|deleterequested` - Limit display to projects based on state; the default is `active`
@@ -781,6 +781,14 @@ Here are some sample values:
Create a new Service Account private key; all existing private keys remain valid.
The `oauth2service.json` file is updated with the new private key.
This command requires that the current Service Account private key is valid, if you get the following error:
```
ERROR: 401: authError - Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.
```
see: [Upload a Service Account key to a service account without a valid private key](#upload-a-service-account-key-to-a-service-account-without-a-valid-private-key)
Keep a good record of where each Service Account key is used as the keys themselves do not record this information.
The two forms of the command are equivalent; the second form is used by Legacy GAM.
@@ -809,6 +817,14 @@ The `oauth2service.json` file is updated with the new private key. If you had pr
this `oauth2service.json` file to other users, you must redistribute the updated file as the private key
in the distributed copies has been revoked.
This command requires that the current Service Account private key is valid, if you get the following error:
```
ERROR: 401: authError - Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.
```
see: [Upload a Service Account key to a service account without a valid private key](#upload-a-service-account-key-to-a-service-account-without-a-valid-private-key)
The two forms of the command are equivalent; the second form is used by Legacy GAM.
```
gam update sakey
@@ -828,6 +844,14 @@ in the distributed copies has been revoked.
This command can be used if your Service Account keys have been compromised; all existing private keys are revoked.
This command requires that the current Service Account private key is valid, if you get the following error:
```
ERROR: 401: authError - Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.
```
see: [Upload a Service Account key to a service account without a valid private key](#upload-a-service-account-key-to-a-service-account-without-a-valid-private-key)
The two forms of the command are equivalent; the second form is used by Legacy GAM.
```
gam replace sakeys
@@ -844,25 +868,20 @@ You can delete Service Accounts keys thus revoking access for that key. Generall
delete a service account key for a distributed copy of an `oauth2service.json` file to disable
that user's service account access.
This command requires that the current Service Account private key is valid, if you get the following error:
```
ERROR: 401: authError - Request had invalid authentication credentials.
Expected OAuth 2 access token, login cookie or other valid authentication credential.
See https://developers.google.com/identity/sign-in/web/devconsole-project.
```
see: [Upload a Service Account key to a service account without a valid private key](#upload-a-service-account-key-to-a-service-account-without-a-valid-private-key)
You can disable your current Service Account key if you specify the `doit` argument. This is your
acknowledgement that you will have to manually create a new Service Account key in the Developer's Console
or upload a new key with the `gam upload sakey` command.
```
gam delete sakeys <ServiceAccountKeyList>+ [doit]
```
## Upload a Service Account key to a service account with no keys
There are two cases where you will use this command:
* Your workspace is configured to disable service account private key uploads and you are creating a project.
* All of your service account keys have been deleted, either manually or with the `gam delete sakeys` command.
The `oauth2service.json` file is updated with the new private key. If you had previously distributed
any `oauth2service.json` file to other users, you must redistribute the updated file with the new key.
By default, the `print course-counts` command displays participant counts about all courses.
To get participant counts for a specific set of courses, use the following option; it can be repeated to select multiple courses.
* `(course|class <CourseID>)*` - Display courses with the specified `<CourseID>`.
To get participant counts for courses based on their having a particular participant, use the following options. Both options can be specified.
* `teacher <UserItem>` - Display courses with the specified teacher.
* `student <UserItem>` - Display courses with the specified student.
To get participant counts for courses based on their state, use the following option. This option can be combined with the `teacher` and `student` options.
By default, all course states are selected.
* `states <CourseStateList>` - Display courses with any of the specified states.
By default, all count values are displayed, use `mincount <Integer>` to limit the display to those counts
greater that or equal to the specified `<Integer>`.
By default, Gam displays the counts as columns of fields; the following option causes the output to be in JSON format,
* `formatjson` - Display the fields in JSON format.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
The `quotechar <Character>` option allows you to choose an alternate quote character, single quote for instance, that makes for readable/processable output.
`quotechar` defaults to `gam.cfg/csv_output_quote_char`. When uploading CSV files to Google, double quote `"` should be used.
### Example
For teachers in all active courses, print the number of classes for which they are a participant.
```
gam print coursecounts teachers states active
```
For teachers in all active courses, print the number of classes (if it is >= 5) for which they are a participant.
```
gam print coursecounts teachers states active mincount 5
By default, all groups in the account are displayed, these options allow selection of subsets of groups:
@@ -385,9 +386,15 @@ Members that have met the above qualifications to be displayed can be further qu
*`memberemaildisplaypattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will be displayed; others will not be displayed
*`memberemailskippattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will not be displayed; others will be displayed
Add additional columns of data from the command line to the output
*`addcsvdata <FieldName> <String>`
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
*`formatjson` - Display the fields in JSON format.
If `formatjson` and `addcsvdata` are specified, the option `includecsvdatainjson` causes GAM to add the
additional field values to the JSON data.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
By default, all groups in the account are displayed, these options allow selection of subsets of groups:
@@ -569,9 +570,15 @@ Members that have met the above qualifications to be displayed can be further qu
*`memberemaildisplaypattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will be displayed; others will not be displayed
*`memberemailskippattern <REMatchPattern>` - Members with email addresses that match `<REMatchPattern>` will not be displayed; others will be displayed
Add additional columns of data from the command line to the output
*`addcsvdata <FieldName> <String>`
By default, Gam displays the information as columns of fields; the following option causes the output to be in JSON format,
*`formatjson` - Display the fields in JSON format.
If `formatjson` and `addcsvdata` are specified, the option `includecsvdatainjson` causes GAM to add the
additional field values to the JSON data.
By default, when writing CSV files, Gam uses a quote character of double quote `"`. The quote character is used to enclose columns that contain
the quote character itself, the column delimiter (comma by default) and new-line characters. Any quote characters within the column are doubled.
When using the `formatjson` option, double quotes are used extensively in the data resulting in hard to read/process output.
@@ -10,7 +10,36 @@ To run all commands properly, GAM7 requires three things:
* A special service account that is authorized to act on behalf of your users in order to modify user-specific settings and data such as Drive files, Calendars and Gmail messages and settings like signatures.
# Documentation
See the sections in the right-hand column for documentation.
## Update History
A log of updates to GAM7.
## Installation
Instructions detailing ways of installing GAM7 and alternate installation issues.
## Configuration
Instructions detailing configuration of GAM7 and alternate authorization methods.
## Notes and Information
References to resources that enhance your use of GAM7.
## Definitions
BNF definitions of common items in the GAM7 command syntax.
## Command Processing
Information regarding use of command line options to control how GAM7 operates.
## Collections
BNF Syntax definitions of ways to specify multiple Googlw Workspace opjects.
## Client Access
Syntax, descriptions and examples of commands that are executed by your Google Workspace administrator.
## Special Service Account Access
How to set up a GAM7 Chat Bot; this is required to use the Chat API to manage Chat Spaces in your Google Workspace.
## Service Account Access
Syntax, descriptions and examples of commands that are executed on behalf of your Google Workspace users.
Select the application with `<ActivityApplicationName>`.
For all `<ActivityApplicationNames>` other than `admin`, select the users for whom information is desired.
For all `<ActivityApplicationNames>`, select the users for whom information is desired.
*`user all` - All users, the default; there is one API call
*`user <UserItem>` - An individual user; there is one API call
*`orgunit|org|ou <OrgUnitPath>` - All users in the specified OU; there is one API call
*`showorgunit` - Add a column labelled `actor.orgUnitPath` to the output; an additional API call is made to get the email addresses of the users in `<OrgUnitPath>`
*`select <UserTypeEntity>` - A selected collection of users, e.g., `select group staff@domain.com`; there is one API call per user
For `<ActivityApplicationName>``admin`, the users selected are the admins that executed the command, not the targeted user.
Use `filter "USER_EMAIL==user@domain.com"` to select the targeted user.
For `<ActivityApplicationName>``admin` and `chrome`, `orgunit|org|ou <OrgUnitPath>` does not work, use `select ou <OrgUnitPath>`.
For `<ActivityApplicationName>``admin`, use option `userisactor` to display activities where the user executed the command that generated the activity.
Limit the time period.
*`start <Time>`
@@ -102,6 +125,15 @@ Limit the time period.
*`thismonth` - The current calendar month up to the current time
*`previousmonths <Integer>` - A number in the range 1 to 6 indicating calendar months previous to the current month
For `gam report gmail`, `start <Time>` and `end <Time>`should both be provided, and the scan duration should not be greater than 30 days.
GAM will supply missing values:
* No time information provided - GAM sets `range -30d today`
* Only `start <Time>` provided - GAM sets `end <Time>+30d`
* Only `end <Time>` provided - GAM sets `start <Time>-30d`
For `gam report gmail`, `gmaileventtypes <NumberRangeList>` can be used to limit the event types displayed.
This option is only available when the command is run as an administrator.
@@ -649,15 +668,23 @@ When deleting permissions from JSON data, permissions with role `owner` true are
These commands are used to transfer ACLs from one Shared Drive to another.
* `copy` - Copy all ACLs from the source Shared Drive to the target Shared Drive. The role of an existing ACL in the target Shared Drive will never be reduced.
* `sync` - Add/delete/update ACLs in the target Shared Drive to match those in the source Shared Drive.
* `<UserTypeEntity>` - Not Specified
* All Shared Drives must be in the same workspace as the admin in `oauth2.txt`.
* `<UserTypeEntity>` - Specified
* `adminaccess|asadmin` specified - All Shared Drives must be in the same workspace as `<UserTypeEntity>`.
* `adminaccess|asadmin` not specified - Shared Drives can be in separate workspaces if `<UserTypeEntity>` in a manager of all of them.
```
gam [<UserTypeEntity>] copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
@@ -665,8 +692,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specifed, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DonainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to me mapped.
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
If `<UserCalendarEntity>` is not specified, all of a user's owned secondary calendars will be transferrdd.
By default, the users in `<UserTypeEntity>` retain no role in the transferred calendars.
*`keepuser` - The users in `<UserTypeEntity>` retain their ownership.
*`retainrole <CalendarACLRole>` - The users in `<UserTypeEntity>` retain the specified role.
*`noretentionmessages` - Suppress the original owner role retention messages.
This capability is no longer available, see: https://developers.google.com/workspace/calendar/release-notes#October_27_2025
By default, when you add or update a calendar ACL, a notification is sent to the affected users; use `sendnotifications false` to suppress sending the notifications.
Data ownership can be transferred in the Google Calendar UI.
You can update calendar settings as part of the transfer. In description, location and summary, #email#, #user# and #username# will be replaced
by the original owner's full email address or just the name portion; #timestamp# will be replaced by the current date and time.
*`<CalendarSettings>` - The value specified will replace the existing value.
*`append description|location|summary` - The specified <CalendarSettings> value will be appended to the existing value.
*`noupdatemessages` - Suppress the settings update messages.
You can manipulate the old and new owner's calendar lists.
*`deletefromoldowner` - Delete the calendar from the old owner's calendar list
*`addtonewowner <CalendarAttribute>*` - Add the calendar to the new owner's calendar list; optionally specify attributes
*`nolistmessages` - Suppress the calendar list add/delete messages.
### Example
Transfer a secondary calendar from oldowner to newowner. Remove the calendar from the old owner's calendar list and add to the new owner's calendar list.
```
gam user oldowner@domain.com transfer calendars newowner@domain.com c_aaa123zzz@group.calendar.google.com removefromoldowner addtonewowner
```
Transfer ownership of all non-primary calendars from oldowner to newowner; append a message to the calendar description noting the old owner and the time of transfer.
```
gam user oldowner@domain.com transfer calendars newowner@domain.com minaccessrole owner description "(Transferred from #user# on #timestamp#)" append description
@@ -177,9 +193,13 @@ You can specify `<REMatchPattern>` patterns that limit the items copied based on
*`shortcutnamematchpattern <REMatchPattern>` - Only shortcuts whose name matches `<REMatchPattern>` are copied
### By default, when copying sub files, all files, regardless of ownership, are copied.
*`copysubfilesownedby any` - All files, regardless of ownership, are copied.
*`copysubfilesownedby any` - All files, regardless of ownership, are copied; this is the default.
*`copysubfilesownedby me` - Only files owned by `<UserTypeEntity>` are copied.
*`copysubfilesownedby others` - Only files not owned by `<UserTypeEntity>` are copied.
*`copysubfilesownedby users <EmailAddressList>` - Only files owned by users in `<EmailAddressList>` are copied.
*`copysubfilesownedby notusers <EmailAddressList>` - Only files not owned by users in `<EmailAddressList>` are copied.
*`copysubfilesownedby regex <REMatchPattern>` - Only files owned by users whose email addresses match `<REMatchPattern>` are copied.
*`copysubfilesownedby notregex <REMatchPattern>` - Only files owned by users whose email addresses do not match `<REMatchPattern>` are copied.
### Specify a new name for the file/folder
*`newfilename <DriveFileName>` - The copied file/folder will be named `<DriveFileName>`
@@ -313,8 +333,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specified, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to me mapped.
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
When copying an ACL that references a non Google account, an error is generated unless an email is sent to the account;
by default, no email notifications are sent. The `sendemailifrequired` options instructs GAM to send an email notification in this case.
@@ -666,8 +692,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can ge specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specified, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to me mapped.
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
When copying an ACL that references a non Google account, an error is generated unless an email is sent to the account;
by default, no email notifications are sent. The `sendemailifrequired` options instructs GAM to send an email notification in this case.
@@ -684,8 +716,14 @@ When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that
When `includepermissionsfromdomains <DomainNameList>` is specified, any ACLs that references a domain not in `<DomainNameList>` will be removed.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be removed;
a new ACL with the same properties referencing the second `<EmailAddess>` will be created. The option can be repeated if multiple domain names are to be mapped.
Bulk email address mapping can ge specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specified, any ACL that references the first `<DomainName>` will be removed;
a new ACL with the same properties referencing the second `<DomainName>` will be created. The option can be repeated if multiple domain names are to me mapped.
a new ACL with the same properties referencing the second `<DomainName>` will be created. The option can be repeated if multiple domain names are to be mapped.
When creating an ACL that references a non Google account, an error is generated unless an email is sent to the account;
by default, no email notifications are sent. The `sendemailifrequired` options instructs GAM to send an email notification in this case.
@@ -692,6 +693,7 @@ The `dateheaderconverttimezone [<Boolean>]>` option converts `<SMTPDateHeader>`
## Print only options
These options are valid with `print`.
*`convertcrnl` - In the message body, convert carriage returns to `\r` and newlines to `\n`; the default value is `csv_output_convert_cr_nl` from `gam.cfg`.
*`addcsvdata <FieldName> <String>` - Add additional columns of data from the command line to the output
By default, message attachment information is not displayed.
*`showattachments` - Display attachment filename, MIME type and size
@@ -516,6 +527,40 @@ When adding permissions from JSON data, permissions with `deleted` true are neve
When deleting permissions from JSON data, permissions with role `owner` true are never processed.
## Transfer Shared Drive access
These commands are used to transfer ACLs from one Shared Drive to another.
*`copy` - Copy all ACLs from the source Shared Drive to the target Shared Drive. The role of an existing ACL in the target Shared Drive will never be reduced.
*`sync` - Add/delete/update ACLs in the target Shared Drive to match those in the source Shared Drive.
*`adminaccess|asadmin` specified - All Shared Drives must be in the same workspace as `<UserTypeEntity>`.
*`adminaccess|asadmin` not specified - Shared Drives can be in separate workspaces if `<UserTypeEntity>` in a manager of all of them.
```
gam <UserTypeEntity> copy shareddriveacls <SharedDriveEntity> to <SharedDriveEntity>
When `excludepermissionsfromdomains <DomainNameList>` is specified, any ACL that references a domain in `<DomainNameList>` will not be copied.
When `includepermissionsfromdomains <DomainNameList>` is specified, only ACLs that reference a domain in `<DomainNameList>` will be copied.
When `mappermissionsemail <EmailAddress> <EmailAddress>` is specifed, an ACL that references the first `<EmailAddress>` will be modified
to reference the second `<EmailAddress>` when copied; the original ACL is not modified. The option can be repeated if multiple email addresses are to be mapped.
Bulk permission email address mapping can be specified with `mappermissionsemailfile <CSVFileInput> endcsv`.
`<CSVFileInput>` must include these columns: `sourceEmail` and `destinationEmail`.
When `mappermissionsdomain <DomainName> <DomainName>` is specifed, any ACL that references the first `<DomainName>` will be modified
to reference the second `<DomainName>` when copied; the original ACL is not modified. The option can be repeated if multiple domain names are to be mapped.
## Display Shared Drive access
These commands are used to display the ACLs on Shared Drives themselves, not the files/folders on the Shared Drives.
@@ -29,23 +29,32 @@ No, because the YubiKey generated the private key it cannot be digitally exporte
When using domain-wide delegation with GAM7, the service account and anyone possessing the service account private key oauth2service.json file has access to the Gmail, Drive and Calendar data of ALL Workspace users in your domain. For this reason, whether using a YubiKey or not, you should take strong measures to protect the service account private key.
## Setup Steps
1 .Upgrade to the [latest version of GAM7](https://github.com/GAM-team/GAM/wiki/How-to-Update-GAM7).
2.**If you are using a new YubiKey or don't care about the PIV app data on the YubiKey**
1. Tell GAM7 to reset and configure the PIV app data on the YubiKey. This wipes all existing keys and configuration and then configures a private key and PIN for GAM7.
1.Upgrade to the [latest version of GAM7](https://github.com/GAM-team/GAM/wiki/How-to-Update-GAM7).
2. If you are using a new YubiKey or don't care about the PIV app data on the YubiKey:
a. Tell GAM7 to reset and configure the PIV app data on the YubiKey. This wipes all existing keys and configuration and then configures a private key and PIN for GAM7.
* Use `9a` for the `AUTHENTICATION` slot, `9c` for the `SIGNATURE` slot
5. Now that you have a private key on your YubiKey, tell GAM7 to use that instead of the private_key stored in oauth2service.json. We can do that by rotating the key:
4. Now that you have a private key on your YubiKey, tell GAM7 to use that instead of the private_key stored in oauth2service.json. We can do that by rotating the key:
@@ -58,10 +67,10 @@ copy oauth2service.json to oauth2service.yk
copy oauth2service.save to oauth2service.json
```
6. Now you should be able to run GAM7 commands like:
5. Now you should be able to run GAM7 commands like:
```
gam user admin@example.com check serviceaccount
```
and see the YubiKey lights flash as the YubiKey interacts with GAM7 to sign the GAM7 authentication requests. If you look at the oauth2service.json file, you'll see it contains some new fields like yubikey_serial and yubikey_pin but no longer contains the private_key field where GAM7 would normally store the private key data.
7. As a last step, since YubiKey-stored private keys do not need to be and should not be rotated, you can remove the service account's permissions to change it's own key. Navigate to the [Cloud Console](https://console.cloud.google.com/iam-admin/serviceaccounts) select the correct project and service account and on the Permissions tab, edit and remove the "Service Account Key Admin" permission that the service account has to itself.
6. As a last step, since YubiKey-stored private keys do not need to be and should not be rotated, you can remove the service account's permissions to change it's own key. Navigate to the [Cloud Console](https://console.cloud.google.com/iam-admin/serviceaccounts) select the correct project and service account and on the Permissions tab, edit and remove the "Service Account Key Admin" permission that the service account has to itself.
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.