mirror of
https://github.com/prowler-cloud/prowler.git
synced 2026-01-25 02:08:11 +00:00
feat(microsof365): Add documentation and compliance file (#6195)
Co-authored-by: MrCloudSec <hello@mistercloudsec.com> Co-authored-by: Daniel Barranquero <74871504+danibarranqueroo@users.noreply.github.com>
This commit is contained in:
committed by
GitHub
parent
ff35fd90fa
commit
dcb9267c2f
@@ -75,6 +75,7 @@ It contains hundreds of controls covering CIS, NIST 800, NIST CSF, CISA, RBI, Fe
|
||||
| GCP | 77 | 13 | 4 | 3 |
|
||||
| Azure | 140 | 18 | 5 | 3 |
|
||||
| Kubernetes | 83 | 7 | 2 | 7 |
|
||||
| Microsoft365 | 5 | 2 | 1 | 0 |
|
||||
|
||||
> You can list the checks, services, compliance frameworks and categories with `prowler <provider> --list-checks`, `prowler <provider> --list-services`, `prowler <provider> --list-compliance` and `prowler <provider> --list-categories`.
|
||||
|
||||
|
||||
@@ -175,6 +175,7 @@ Due to the complexity and differences of each provider use the rest of the provi
|
||||
- [GCP](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/gcp/gcp_provider.py)
|
||||
- [Azure](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/azure/azure_provider.py)
|
||||
- [Kubernetes](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/kubernetes/kubernetes_provider.py)
|
||||
- [Microsoft365](https://github.com/prowler-cloud/prowler/blob/master/prowler/providers/microsoft365/microsoft365_provider.py)
|
||||
|
||||
To facilitate understanding here is a pseudocode of how the most basic provider could be with examples.
|
||||
|
||||
|
||||
@@ -237,3 +237,4 @@ It is really important to check if the current Prowler's permissions for each pr
|
||||
- AWS: https://docs.prowler.cloud/en/latest/getting-started/requirements/#aws-authentication
|
||||
- Azure: https://docs.prowler.cloud/en/latest/getting-started/requirements/#permissions
|
||||
- GCP: https://docs.prowler.cloud/en/latest/getting-started/requirements/#gcp-authentication
|
||||
- Microsoft365: https://docs.prowler.cloud/en/latest/getting-started/requirements/#microsoft365-authentication
|
||||
|
||||
@@ -102,3 +102,32 @@ Those credentials must be associated to a user or service account with proper pe
|
||||
|
||||
???+ note
|
||||
By default, `prowler` will scan all accessible GCP Projects, use flag `--project-ids` to specify the projects to be scanned.
|
||||
|
||||
## Microsoft365
|
||||
|
||||
Prowler for Microsoft365 currently supports the following authentication types:
|
||||
|
||||
- [Service principal application](https://learn.microsoft.com/en-us/entra/identity-platform/app-objects-and-service-principals?tabs=browser#service-principal-object) (recommended).
|
||||
- Current az cli credentials stored.
|
||||
- Interactive browser authentication.
|
||||
|
||||
|
||||
???+ warning
|
||||
For Prowler App only the Service Principal with an application authentication method is supported.
|
||||
|
||||
### Service Principal authentication
|
||||
|
||||
To allow Prowler assume the service principal identity to start the scan it is needed to configure the following environment variables:
|
||||
|
||||
```console
|
||||
export AZURE_CLIENT_ID="XXXXXXXXX"
|
||||
export AZURE_CLIENT_SECRET="XXXXXXXXX"
|
||||
export AZURE_TENANT_ID="XXXXXXXXX"
|
||||
```
|
||||
|
||||
If you try to execute Prowler with the `--sp-env-auth` flag and those variables are empty or not exported, the execution is going to fail.
|
||||
Follow the instructions in the [Create Prowler Service Principal](../tutorials/azure/create-prowler-service-principal.md) section to create a service principal.
|
||||
|
||||
### Interactive Browser authentication
|
||||
|
||||
To use `--browser-auth` the user needs to authenticate against Azure using the default browser to start the scan, also `--tenant-id` flag is required.
|
||||
|
||||
@@ -164,7 +164,7 @@ Prowler is available as a project in [PyPI](https://pypi.org/project/prowler/),
|
||||
|
||||
* `Python >= 3.9`
|
||||
* `Python pip >= 21.0.0`
|
||||
* AWS, GCP, Azure and/or Kubernetes credentials
|
||||
* AWS, GCP, Azure, Microsoft365 and/or Kubernetes credentials
|
||||
|
||||
_Commands_:
|
||||
|
||||
@@ -417,7 +417,7 @@ While the scan is running, start exploring the findings in these sections:
|
||||
|
||||
### Prowler CLI
|
||||
|
||||
To run Prowler, you will need to specify the provider (e.g `aws`, `gcp`, `azure` or `kubernetes`):
|
||||
To run Prowler, you will need to specify the provider (e.g `aws`, `gcp`, `azure`, `microsoft365` or `kubernetes`):
|
||||
|
||||
???+ note
|
||||
If no provider specified, AWS will be used for backward compatibility with most of v2 options.
|
||||
@@ -559,5 +559,23 @@ kubectl logs prowler-XXXXX --namespace prowler-ns
|
||||
???+ note
|
||||
By default, `prowler` will scan all namespaces in your active Kubernetes context. Use the flag `--context` to specify the context to be scanned and `--namespaces` to specify the namespaces to be scanned.
|
||||
|
||||
#### Microsoft365
|
||||
|
||||
With Microsoft365 you need to specify which auth method is going to be used:
|
||||
|
||||
```console
|
||||
# To use service principal authentication
|
||||
prowler microsoft365 --sp-env-auth
|
||||
|
||||
# To use az cli authentication
|
||||
prowler microsoft365 --az-cli-auth
|
||||
|
||||
# To use browser authentication
|
||||
prowler microsoft365 --browser-auth --tenant-id "XXXXXXXX"
|
||||
|
||||
```
|
||||
|
||||
See more details about Microsoft365 Authentication in [Requirements](getting-started/requirements.md#microsoft365)
|
||||
|
||||
## Prowler v2 Documentation
|
||||
For **Prowler v2 Documentation**, please check it out [here](https://github.com/prowler-cloud/prowler/blob/8818f47333a0c1c1a457453c87af0ea5b89a385f/README.md).
|
||||
|
||||
@@ -4,7 +4,7 @@ To allow Prowler assume an identity to start the scan with the required privileg
|
||||
|
||||
To create a Service Principal Application you can use the Azure Portal or the Azure CLI.
|
||||
|
||||
## From Azure Portal
|
||||
## From Azure Portal / Entra Admin Center
|
||||
|
||||
1. Access to Microsoft Entra ID
|
||||
2. In the left menu bar, go to "App registrations"
|
||||
|
||||
23
docs/tutorials/microsoft365/authentication.md
Normal file
23
docs/tutorials/microsoft365/authentication.md
Normal file
@@ -0,0 +1,23 @@
|
||||
# Microsoft365 authentication
|
||||
|
||||
By default Prowler uses MsGraph Python SDK identity package authentication methods using the class `ClientSecretCredential`.
|
||||
This allows Prowler to authenticate against microsoft365 using the following methods:
|
||||
|
||||
- Service principal authentication by environment variables (Enterprise Application)
|
||||
- Current CLI credentials stored
|
||||
- Interactive browser authentication
|
||||
|
||||
To launch the tool first you need to specify which method is used through the following flags:
|
||||
|
||||
```console
|
||||
# To use service principal authentication
|
||||
prowler microsoft365 --sp-env-auth
|
||||
|
||||
# To use cli authentication
|
||||
prowler microsoft365 --az-cli-auth
|
||||
|
||||
# To use browser authentication
|
||||
prowler microsoft365 --browser-auth --tenant-id "XXXXXXXX"
|
||||
```
|
||||
|
||||
To use Prowler you need to set up also the permissions required to access your resources in your Microsoft365 account, to more details refer to [Requirements](../../getting-started/requirements.md)
|
||||
@@ -94,6 +94,9 @@ nav:
|
||||
- In-Cluster Execution: tutorials/kubernetes/in-cluster.md
|
||||
- Non In-Cluster Execution: tutorials/kubernetes/outside-cluster.md
|
||||
- Miscellaneous: tutorials/kubernetes/misc.md
|
||||
- Microsoft 365:
|
||||
- Authentication: tutorials/microsoft365/authentication.md
|
||||
- Create Prowler Service Principal: tutorials/microsoft365/create-prowler-service-principal.md
|
||||
- Developer Guide:
|
||||
- Introduction: developer-guide/introduction.md
|
||||
- Provider: developer-guide/provider.md
|
||||
|
||||
@@ -123,7 +123,10 @@ def load_and_validate_config_file(provider: str, config_file_path: str) -> dict:
|
||||
|
||||
# Not to introduce a breaking change, allow the old format config file without any provider keys
|
||||
# and a new format with a key for each provider to include their configuration values within.
|
||||
if any(key in config_file for key in ["aws", "gcp", "azure", "kubernetes"]):
|
||||
if any(
|
||||
key in config_file
|
||||
for key in ["aws", "gcp", "azure", "kubernetes", "microsoft365"]
|
||||
):
|
||||
config = config_file.get(provider, {})
|
||||
else:
|
||||
config = config_file if config_file else {}
|
||||
|
||||
@@ -42,7 +42,7 @@ class Microsoft365CIS(ComplianceOutput):
|
||||
compliance_row = Microsoft365CISModel(
|
||||
Provider=finding.provider,
|
||||
Description=compliance.Description,
|
||||
SubscriptionId=finding.account_uid,
|
||||
TenantId=finding.account_uid,
|
||||
Location=finding.region,
|
||||
AssessmentDate=str(finding.timestamp),
|
||||
Requirements_Id=requirement.Id,
|
||||
@@ -73,8 +73,8 @@ class Microsoft365CIS(ComplianceOutput):
|
||||
compliance_row = Microsoft365CISModel(
|
||||
Provider=compliance.Provider.lower(),
|
||||
Description=compliance.Description,
|
||||
SubscriptionId="",
|
||||
Location="",
|
||||
TenantId=finding.account_uid,
|
||||
Location=finding.region,
|
||||
AssessmentDate=str(finding.timestamp),
|
||||
Requirements_Id=requirement.Id,
|
||||
Requirements_Description=requirement.Description,
|
||||
|
||||
@@ -73,7 +73,7 @@ class Microsoft365CISModel(BaseModel):
|
||||
|
||||
Provider: str
|
||||
Description: str
|
||||
SubscriptionId: str
|
||||
TenantId: str
|
||||
Location: str
|
||||
AssessmentDate: str
|
||||
Requirements_Id: str
|
||||
|
||||
@@ -0,0 +1,74 @@
|
||||
import csv
|
||||
import json
|
||||
import sys
|
||||
|
||||
# Convert a CSV file following the CIS 4.0 Microsoft365 Benchmark into a Prowler v3.0 Compliance JSON file
|
||||
# CSV fields:
|
||||
# Section #,Recommendation #,Profile,Title,Assessment Status,Description,Rationale Statement,Impact Statement,Remediation Procedure,Audit Procedure,Additional Information,CIS Controls,CIS Safeguards 1 (v8),CIS Safeguards 2 (v8),CIS Safeguards 3 (v8),v8 IG1,v8 IG2,v8 IG3,CIS Safeguards 1 (v7),CIS Safeguards 2 (v7),CIS Safeguards 3 (v7),v7 IG1,v7 IG2,v7 IG3,References,Default Value
|
||||
|
||||
# Get the CSV filename to convert from
|
||||
file_name = sys.argv[1]
|
||||
|
||||
# Create the output JSON object
|
||||
output = {"Framework": "CIS", "Version": "4.0", "Requirements": []}
|
||||
|
||||
# Open the CSV file and read the rows
|
||||
try:
|
||||
with open(file_name, newline="", encoding="utf-8") as f:
|
||||
reader = csv.reader(f, delimiter=",")
|
||||
next(reader) # Skip the header row
|
||||
for row in reader:
|
||||
attribute = {
|
||||
"Section": row[0],
|
||||
"Profile": row[2],
|
||||
"AssessmentStatus": row[4],
|
||||
"Description": row[5],
|
||||
"RationaleStatement": row[6],
|
||||
"ImpactStatement": row[7],
|
||||
"RemediationProcedure": row[8],
|
||||
"AuditProcedure": row[9],
|
||||
"AdditionalInformation": row[10],
|
||||
"References": row[24],
|
||||
}
|
||||
if row[4] != "":
|
||||
output["Requirements"].append(
|
||||
{
|
||||
"Id": row[1],
|
||||
"Description": row[5],
|
||||
"Checks": [],
|
||||
"Attributes": [attribute],
|
||||
}
|
||||
)
|
||||
except UnicodeDecodeError:
|
||||
# If there is an error reading the file with the default encoding, try with ISO-8859-1
|
||||
with open(file_name, newline="", encoding="ISO-8859-1") as f:
|
||||
reader = csv.reader(f, delimiter=",")
|
||||
next(reader) # Skip the header row
|
||||
for row in reader:
|
||||
attribute = {
|
||||
"Section": row[0],
|
||||
"Profile": row[2],
|
||||
"AssessmentStatus": row[4],
|
||||
"Description": row[5],
|
||||
"RationaleStatement": row[6],
|
||||
"ImpactStatement": row[7],
|
||||
"RemediationProcedure": row[8],
|
||||
"AuditProcedure": row[9],
|
||||
"AdditionalInformation": row[10],
|
||||
"References": row[24],
|
||||
}
|
||||
if row[4] != "":
|
||||
output["Requirements"].append(
|
||||
{
|
||||
"Id": row[1],
|
||||
"Description": row[5],
|
||||
"Checks": [],
|
||||
"Attributes": [attribute],
|
||||
}
|
||||
)
|
||||
|
||||
# Save the output JSON file
|
||||
with open("cis_4.0_microsoft365.json", "w", encoding="utf-8") as outfile:
|
||||
json.dump(output, outfile, indent=4, ensure_ascii=False)
|
||||
|
||||
print("Archivo JSON generado exitosamente.")
|
||||
Reference in New Issue
Block a user