audit-labs/audit-tools

A collection of scripts, queries, and other goodies you can use in an audit.

clone: git clone https://gitbay.org/audit-labs/audit-tools.git

v1.0.0: applications/aws/aws_password_policy/gather_policy.sh · raw

 1#!/usr/bin/env bash
 2#
 3# gather_policy.sh
 4# ----------------
 5# 1. Calls AWS CLI to fetch the current IAM password policy.
 6# 2. Captures execution metadata (date, user, host, AWS profile/region, etc.).
 7# 3. Writes a single JSON document (policy_report.json) that the Python
 8#    script can consume.
 9#
10# Prerequisites:
11#   • AWS CLI v2 installed and configured (credentials, default region, etc.)
12#   • jq installed (used to merge JSON objects).  If jq is missing the script
13#     will abort with a helpful message.
14#
15# Usage:
16#   $ chmod +x gather_policy.sh
17#   $ ./gather_policy.sh          # creates policy_report.json in the cwd
18#   $ ./gather_policy.sh -o /tmp/my_report.json   # custom output path
19#
20
21set -euo pipefail
22
23# ---------- Helper ----------
24die() { echo "ERROR: $*" >&2; exit 1; }
25
26# ---------- Argument parsing ----------
27OUTFILE="policy_report.json"
28while [[ $# -gt 0 ]]; do
29    case "$1" in
30        -o|--output)
31            shift
32            [[ -z "${1:-}" ]] && die "Missing argument for -o|--output"
33            OUTFILE="$1"
34            ;;
35        -h|--help)
36            echo "Usage: $0 [-o|--output <path-to-json>]"
37            exit 0
38            ;;
39        *)
40            die "Unknown option: $1"
41            ;;
42    esac
43    shift
44done
45
46# ---------- Verify prerequisites ----------
47command -v aws >/dev/null || die "AWS CLI not found in PATH"
48command -v jq >/dev/null || die "jq not found in PATH – install it (e.g. sudo dnf install jq)"
49
50# ---------- 1. Pull the IAM password policy ----------
51# If no policy exists, AWS returns a NoSuchEntity error – we capture that
52if ! POLICY_JSON=$(aws iam get-account-password-policy 2>/dev/null); then
53    die "No password policy is defined for this AWS account (AWS returned NoSuchEntity)."
54fi
55
56# ---------- 2. Gather metadata ----------
57#   * timestamp (UTC)
58#   * OS user running the script
59#   * hostname
60#   * current working directory (useful for traceability)
61#   * AWS profile & region (if set)
62#   * AWS caller identity (ARN, account id, user id) – proves *who* ran the command
63# Build with `jq --arg` so values containing quotes/backslashes (e.g. an odd
64# hostname or working directory) can never produce malformed JSON.
65CALLER_IDENTITY=$(aws sts get-caller-identity 2>/dev/null || echo "null")
66METADATA=$(jq -n \
67    --arg ts "$(date -u +"%Y-%m-%dT%H:%M:%SZ")" \
68    --arg user "$(id -un)" \
69    --arg host "$(hostname)" \
70    --arg cwd "$(pwd)" \
71    --arg profile "${AWS_PROFILE:-default}" \
72    --arg region "${AWS_DEFAULT_REGION:-unknown}" \
73    --argjson caller "$CALLER_IDENTITY" \
74    '{metadata: {
75        report_timestamp_utc: $ts,
76        os_user: $user,
77        hostname: $host,
78        working_directory: $cwd,
79        aws_profile: $profile,
80        aws_region: $region,
81        aws_caller_identity: $caller
82    }}')
83
84# ---------- 3. Merge policy + metadata ----------
85# The final JSON will have two top‑level keys: "metadata" and "PasswordPolicy"
86FINAL_JSON=$(jq -s 'reduce .[] as $item ({}; . * $item)' <(echo "$METADATA") <(echo "$POLICY_JSON"))
87
88# ---------- 4. Write output ----------
89echo "$FINAL_JSON" | jq '.' > "$OUTFILE"
90
91echo "Password‑policy report written to: $OUTFILE"