Skip to content

Commit

Permalink
Merge branch 'main' into error-handling
Browse files Browse the repository at this point in the history
  • Loading branch information
adhilto authored Jan 30, 2024
2 parents cfdc934 + d6907a1 commit 808b6e4
Show file tree
Hide file tree
Showing 14 changed files with 171 additions and 561 deletions.
99 changes: 67 additions & 32 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,7 @@ For the Microsoft 365 (M365) rendition of this tool, see [ScubaGear](https://git
- [Downloading the OPA executable](#download-the-opa-executable)
- [Permissions](#permissions)
- [Create a Project](#create-a-project)
- [Create an OAuth credential](#create-an-oauth-credential)
- [Add the Oauth App to the allowlist](#add-the-oauth-app-to-the-allowlist)
- [Authentication](#authentication)
- [Usage](#usage)
- [Examples](#example-1-run-an-assessment-against-all-gws-products)
- [Organization](#organization)
Expand Down Expand Up @@ -150,11 +149,18 @@ The tool uses the following OAUTH API scopes.
When running ScubaGoggles for the first time you will be prompted to consent to these API scopes. Users with the Super Admin role automatically have the privilege to consent to these scopes. A custom admin role can also be made with the minimum permissions to consent to these scopes. See this [Google Admin SDK Prerequisites guide](https://developers.google.com/admin-sdk/reports/v1/guides/prerequisites) for more information.

### Create a project
1. If you already have a Google Cloud Project that you want to utilize skip to [Create an OAuth credential](#create-an-oauth-credential)
1. If you already have a Google Cloud Project that you want to utilize skip to [Authentication](#authentication)
2. Otherwise start by signing into http://console.cloud.google.com/.
3. Follow the [directions outlined in this guide to create a project](https://developers.google.com/workspace/guides/create-project)

### Create an OAuth credential
### Authentication

ScubaGoggles supports both OAuth and Service Accounts for authorization/authentication.
OAuth requires regular user consent while using a service account allows for more automation.
Follow the instructions below for the authentication method of your choice.


#### Create an OAuth credential
1. Be signed into http://console.cloud.google.com/.
1. From the hamburger menu on the left, select **APIs & Services** -> **OAuth consent screen**
1. Select **Internal** for **User Type**
Expand Down Expand Up @@ -183,42 +189,66 @@ When running ScubaGoggles for the first time you will be prompted to consent to
1. During the first run of this tool your default web browser will open up a page to consent to the API scopes needed to run this tool. Sign in
with an account with the necessary privileges and click allow.

### Add the Oauth App to the allowlist
##### Add the Oauth App to the allowlist
If you've limited application access to Google's APIs in your organization, the [Common Controls: App Access to Google APIs](https://github.com/cisagov/ScubaGoggles/blob/main/baselines/Common%20Controls%20Minimum%20Viable%20Secure%20Configuration%20Baseline%20v0.1.md#11-app-access-to-google-apis) baseline covers this topic, follow the directions below to allowlist the OAuth app.

1. Login to https://console.cloud.google.com
2. Navigate to the appropriate project
3. Select **API's & Services** from the top left hamburger icon
4. Select **Credentials**
5. Copy your client ID under **OAuth 2.0 Client IDs**

#### GWS Admin Console

1. Navigate to **Security** -> **Access and Data Control** -> **API Controls** -> **Manage Third-Party App Access**
2. Select **Add App** -> **Oauth App Name** or **Client ID**
3. Search by your **OAuth client ID**
4. Select the App
5. Select your root organization as the domain
6. Select **Trusted**
1. Navigate to the appropriate project
1. Select **API's & Services** from the top left hamburger icon
1. Select **Credentials**
1. Copy your client ID under **OAuth 2.0 Client IDs**
1. Now login to [admin.google.com](https://admin.google.com/) and navigate to **Security** -> **Access and Data Control** -> **API Controls** -> **Manage Third-Party App Access**
1. Select **Add App** -> **Oauth App Name** or **Client ID**
1. Search by your **OAuth client ID**
1. Select the App
1. Select your root organization as the domain
1. Select **Trusted**

#### Using a Service Account

> [!Important]
> ScubaGoggles requires the service account to have [domain-wide delegation of authority](https://support.google.com/a/answer/162106?hl=en) to function.
1. Login to https://console.cloud.google.com and navigate to your GCP project.
1. From the hamburger menu, select **IAM & Admin** -> **Service Accounts**
1. Double click on the newly created service account then click **KEYS** -> **ADD KEY** -> **Create new key** -> **JSON** -> **CREATE**
1. Move the downloaded file (begins with `<service account>*.json`) to the root directory folder of this repo, rename to `credentials.json`
1. Now login to [admin.google.com](https://admin.google.com/) and navigate to **Security** -> **Access and data control** -> **API controls**
1. Select **MANAGE DOMAIN WIDE DELEGATION**
1. Select **Add new**
1. Enter the `client_id` from the downloaded credentials (also visible after double clicking on the created Service account under Details -> Unique ID)
1. Enter each OAuth scope as listed in [OAuth API Scopes](#oauth-api-scopes)
1. Select **AUTHORIZE**
1. Finally, run ScubaGoggles with the `--subjectemail` option set to the email of an admin with necessary permissions to run ScubaGoggles.

> [!NOTE]
> ScubaGoggles can be run using a service account in a different organization.
> To do so, specify the `--customerid` argument with the customer ID of the target organization (found in [admin.google.com](https://admin.google.com/) under **Account** -> **Account settings**)
## Usage
Execute the ScubaGoggles tool using the `scubagoggles` command. For GWS, all commands will be under the `gws` subparser.

```
scubagoggles gws -h
usage: scubagoggles gws [-h] [-b [...]] [-o] [-c] [--opapath] [--regopath] [--documentpath] [--runcached]
[--skipexport] [--outputfoldername] [--outputproviderfilename] [--outputregofilename]
[--outputreportfilename] [--debug]
usage: scubagoggles gws [-h] [-b [...]] [-o] [-c] [--subjectemail] [--customerid] [--opapath] [--regopath] [--documentpath]
[--runcached] [--skipexport] [--outputfoldername] [--outputproviderfilename]
[--outputregofilename] [--outputreportfilename] [--omitsudo] [--quiet] [--debug]
options:
optional arguments:
-h, --help show this help message and exit
-b [ ...], --baselines [ ...]
A list of one or more abbreviated GWS baseline names that the tool will assess. Defaults to all
baselines. Choices: gmail, calendar, groups, chat, drive, meet, sites, commoncontrols, rules
A list of one or more abbreviated GWS baseline names that the tool will assess. Defaults to
all baselines. Choices: gmail, calendar, groups, chat, drive, meet, sites, commoncontrols,
rules, classroom
-o , --outputpath The folder path where both the output JSON & HTML report will be created. Defaults to "./" The
current directory.
-c , --credentials The relative path and name of the OAuth credentials json file. Defaults to "./credentials.json"
which means the tool will look for the file named credentials.json in the current directory.
-c , --credentials The relative path and name of the OAuth / service account credentials json file. Defaults to
"./credentials.json" which means the tool will look for the file named credentials.json in the
current directory.
--subjectemail Only applicable when using a service account. The email address of a user the service account
should act on behalf of. This user must have the necessary privileges to run scubagoggles.
--customerid The customer ID the tool should run on. Defaults to "my_customer" which will be the domain of
the user / service account authenticating.
--opapath The relative path to the directory containing the OPA executable. Defaults to "./" the current
executing directory.
--regopath The relative path to the directory contain the folder containing the rego files. Defaults to
Expand All @@ -232,16 +262,16 @@ options:
--outputfoldername The name of the folder created in --outputpath where both the output JSON and the HTML report
will be created. Defaults to GWSBaselineConformance. The client's local timestamp will be
appended to this name.
--outputproviderfilename
--outputproviderfilename
The name of the Provider output json in --outputpath. Defaults to ProviderSettingsExport.
--outputregofilename
--outputregofilename
The name of the Rego output json in --outputpath. Defaults to TestResults.
--outputreportfilename
--outputreportfilename
The name of the main html file homepage created in --outputpath. Defaults to BaselineReports.
--omitsudo This switch prevents running the OPA executable with sudo.
--quiet This switch suppresses automatically launching a web browser to open the html report output and
the loading bar output.
--debug This switch is used to print debugging information for OPA
--quiet This switch suppresses automatically launching a web browser to open the html report output
and the loading bar output.
--debug This switch is used to print debugging information for OPA.
```

### Example 1: Run an assessment against all GWS products
Expand All @@ -267,6 +297,11 @@ scubagoggles gws -b calendar gmail groups chat meet sites -o ./output
scubagoggles gws --runcached --skipexport
```

### Example 5: Run with a service account on a different tenant
```
scubagoggles gws --customerid <customer_id> --subjectemail [email protected]
```

See the `help` options yourself
```
scubagoggles gws -h
Expand Down
12 changes: 8 additions & 4 deletions Testing/RegoTests/gmail/gmail02_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ test_DKIM_Correct_V1 if {
"domain": "test.name",
"rdata": ["v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlaknWsKvtbTLAxtWSF5sDt"]
}
]
],
"domains": ["test.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand All @@ -37,7 +38,8 @@ test_DKIM_Correct_V2 if {
"domain": "test2.name",
"rdata": ["v=DKIM1;"]
}
]
],
"domains": ["test1.name", "test2.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand All @@ -60,7 +62,8 @@ test_DKIM_Incorrect_V1 if {
"domain": "test2.name",
"rdata": []
}
]
],
"domains": ["test1.name", "test2.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand All @@ -79,7 +82,8 @@ test_DKIM_Incorrect_V2 if {
"domain": "test.name",
"rdata": []
}
]
],
"domains": ["test.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand Down
44 changes: 8 additions & 36 deletions Testing/RegoTests/gmail/gmail03_test.rego
Original file line number Diff line number Diff line change
Expand Up @@ -31,18 +31,13 @@ test_SPF_Correct_V1 if {
# Test SPF when there's only one domain
PolicyId := "GWS.GMAIL.3.2v0.1"
Output := tests with input as {
"dkim_records": [
{
"domain": "test.name",
"rdata": ["v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlaknWsKvtbTLAxtWSF5sDt+"]
}
],
"spf_records": [
{
"domain": "test.name",
"rdata": ["v=spf1 include:_spf.google.com ~all"]
}
]
],
"domains": ["test.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand All @@ -56,16 +51,6 @@ test_SPF_Correct_V2 if {
# Test SPF when there's multiple domains
PolicyId := "GWS.GMAIL.3.2v0.1"
Output := tests with input as {
"dkim_records": [
{
"domain": "test1.name",
"rdata": ["v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlaknWsKvtbTLAxtWSF5sDt+"]
},
{
"domain": "test2.name",
"rdata": ["v=DKIM1;"]
}
],
"spf_records": [
{
"domain": "test1.name",
Expand All @@ -75,7 +60,8 @@ test_SPF_Correct_V2 if {
"domain": "test2.name",
"rdata": ["v=spf1 "]
}
]
],
"domains": ["test1.name", "test2.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand All @@ -89,16 +75,6 @@ test_SPF_Incorrect_V1 if {
# Test SPF when there's multiple domains and only one is correct
PolicyId := "GWS.GMAIL.3.2v0.1"
Output := tests with input as {
"dkim_records": [
{
"domain": "test1.name",
"rdata": ["v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlaknWsKvtbTLAxtWSF5sDt+"]
},
{
"domain": "test2.name",
"rdata": ["v=DKIM1;"]
}
],
"spf_records": [
{
"domain": "test1.name",
Expand All @@ -108,7 +84,8 @@ test_SPF_Incorrect_V1 if {
"domain": "test2.name",
"rdata": []
}
]
],
"domains": ["test1.name", "test2.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand All @@ -122,18 +99,13 @@ test_SPF_Incorrect_V2 if {
# Test SPF when there's only one domain and it's wrong
PolicyId := "GWS.GMAIL.3.2v0.1"
Output := tests with input as {
"dkim_records": [
{
"domain": "test.name",
"rdata": ["v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAlaknWsKvtbTLAxtWSF5sDt+"]
}
],
"spf_records": [
{
"domain": "test.name",
"rdata": []
}
]
],
"domains": ["test.name"]
}

RuleOutput := [Result | some Result in Output; Result.PolicyId == PolicyId]
Expand Down
Loading

0 comments on commit 808b6e4

Please sign in to comment.