sudo chown -R root:gam-admins /opt/gam-config
sudo chmod -R 770 /opt/gam-config
sudo chmod g+s /opt/gam-config
sudo chmod g+s /opt/gam-config/gamcache
sudo chmod g+s /opt/gam-config/logs
Run: echo 'export PATH="$HOME/bin:$PATH"' >> ~/.bashrc
Symptom: ERROR: Config file not found. or GAM tries to set up a brand new project for the root user.
Why: sudo by default sanitizes the environment. It strips away the GAMCFGDIR variable you set in .bashrc.
Fix: Train users to never run GAM with sudo. If they absolutely must run it as root (e.g., for a script), they must pass the environment variable explicitly:
sudo --preserve-env=GAMCFGDIR gam info domain
Symptom: The cron job runs but produces an empty file or error logs.
Why: Cron jobs run in a minimal shell. They do not load .bashrc, so they don't know where /opt/gam-config is.
Fix: Always define the variable inside the cron command or script:
# In Crontab:
0 8 * * * export GAMCFGDIR="/opt/gam-config" && /usr/local/bin/gam print users > /tmp/users.csv
Symptom: Error: 403 Insufficient Permission (even though you are a Super Admin).
Why: The oauth2.txt file contains a specific list of "Scopes" (permissions) granted when <Primary_Admin> first ran the setup. It doesn't automatically gain new powers just because you are a Super Admin.
Fix: You must update the token. One admin (it doesn't matter who) must run:
gam oauth create
Select "Select all scopes" (or the specific new ones needed).
Re-authorize via the browser link.
This updates the shared oauth2.txt for everyone.
The Symptom: [Errno 13] Permission denied: '/opt/gam-config/gamcache/...'
Why: If the "Sticky Bit" (chmod g+s) was accidentally removed or didn't propagate to a subdirectory, files created by Jason are owned by jasonchu:jasonchu. Kdong (in group gam-admins) cannot write to them.
Fix: I recommend creating a "Fix Permissions" script that any user can run if things break.
Create /usr/local/bin/fix-gam-perms:
#!/bin/bash
sudo chown -R root:gam-admins /opt/gam-config
sudo chmod -R 770 /opt/gam-config
sudo chmod g+s /opt/gam-config
sudo chmod g+s /opt/gam-config/gamcache
sudo chmod g+s /opt/gam-config/logs
echo "Permissions reset."
Make it executable:
sudo chmod +x /usr/local/bin/fix-gam-perms.
Symptom: 400: invalid_grant or Token Refresh errors.
Why: Google's OAuth servers reject tokens generated by servers with incorrect timestamps to prevent "replay attacks."
Fix: Ensure ntp or systemd-timesyncd is active on the Debian VM.
timedatectl status
# Ensure "System clock synchronized: yes"
Symptom: One admin might see database lock errors or corrupted CSV logs.
Why: GAM uses a local SQLite database in the gamcache folder to track API calls. SQLite handles concurrency well, but if two users try to write to the exact same log file or cache file simultaneously, clashes can happen.
Fix: This is rare, but if you have heavy automation, ensure scripts utilize different output files (which we solved by using gam-${USER}.csv for logging).
Symptom: 401 Unauthorized or invalid_client.
Why: If an admin deletes the Service Account key in the Google Cloud Console but doesn't update the oauth2service.json file in /opt/gam-config, GAM stops working for everyone.
Fix: Establish a policy: "If you rotate the key in Cloud Console, you MUST immediately upload the new JSON to /opt/gam-config."
If GAM breaks in the future, check these in order:
Who: Did you run it with sudo? (Don't).
Where: Is echo $GAMCFGDIR outputting the correct path?
Permissions: Run the fix-gam-perms script.
Time: check date on the server.
Scope: Do you need to run gam oauth create to add new API features?