์ด ์ฃผ์ ์์๋ Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ๋ฅผ ํ์ฉํ์ฌ Secret Manager ๋ฆฌ์์ค๋ฅผ ๋ถ์ํ๋ ๋ฐฉ๋ฒ์ ์์๋ด ๋๋ค.
์ด ๋ด์ฉ์ Secret Manager์ ๋ํ ๊ณ ๊ธ ์ฃผ์ ์ ๋๋ค. ์ด ๊ฐ์ด๋๋ฅผ ์ฝ๊ธฐ ์ ์ ๋ค์ ์ฌํญ์ ๊ฒํ ํ๋ ๊ฒ์ด ์ข์ต๋๋ค.
- Google Cloud ํ๊ฒฝ์ ๋ํ ์ ๋ฐ์ ์ธ ์ดํด๋ฅผ ๋๊ธฐ ์ํ ํ๋ซํผ ๊ฐ์
- Secret Manager์ ๋ํ ์ดํด๋ฅผ ๋๊ธฐ ์ํ Secret Manager ๊ฐ์
- Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ์ ๋ํ ์ดํด๋ฅผ ๋๊ณ ํฌ๊ด์ ์ธ ์ ์ ๊ด๋ฆฌ ๊ธฐ๋ฅ์ ํ์ธํ๊ธฐ ์ํ Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ ๊ฐ์
๊ฐ์
Secret Manager๋ Google Cloud์ ๊ด๋ฆฌํ ๋ฉํ๋ฐ์ดํฐ ์ธ๋ฒคํ ๋ฆฌ ์์คํ ์ธ Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ์ ํตํฉ๋ฉ๋๋ค. ์ด ํตํฉ์ ํตํด ์กฐ์ง, ํด๋ ๋๋ ํ๋ก์ ํธ์์ ๋ณด์ ๋น๋ฐ์ ์๋ณํ๊ณ ๊ฐ์ฌํ ์ ์์ผ๋ฉฐ ์กฐ์ง์ ์๊ตฌ์ฌํญ์ ์ค์ํ์ง ์๋ ๊ตฌ์ฑ์ ๊ฒ์ํ ์ ์์ต๋๋ค. ์ด ๊ฐ์ด๋์์๋ ์ ์ ๋ชจ๋ํฐ๋ง, BigQuery๋ก ์ ์ ๋ด๋ณด๋ด๊ธฐ, Secret Manager ๋ฆฌ์์ค์ ๋ํ Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ ์ฟผ๋ฆฌ ์ํ์ ๋ค๋ฃน๋๋ค.
์ฐธ๊ณ
- ๋ชจ๋ ์ฟผ๋ฆฌ์ Google Cloud CLI ๋ฐ BigQuery๋ก ์์ฑ๋ ์ํ์ด ์์ง๋ง ๋ณด์ ๋น๋ฐ ๋ฐ ๋ณด์ ๋น๋ฐ ๋ฒ์ ์ BigQuery๋ก ๋ด๋ณด๋ด๋ ๊ฒ์ด ์ข์ต๋๋ค. ์ ์ ์ BigQuery๋ก ๋ด๋ณด๋ด๋ฉด SQL๊ณผ ์ ์ฌํ ์ฟผ๋ฆฌ๋ฅผ ์์ฑํ์ฌ ์๋ฏธ ์๋ ๋ถ์์ ์์ฑํ๊ณ ์ ์ฅํ ์ ์์ต๋๋ค.
- Secret Manager๋ ์ ์ ๊ฒ์ ๋๋ ์ ์ฑ ๋ถ์์์ ํตํฉ๋์ง ์์ต๋๋ค. ์๋ ์ฟผ๋ฆฌ๋ Google Cloud CLI ๋ช ๋ น์ค ๋๊ตฌ์ BigQuery์ ๊ธฐ๋ณธ ์์ฑ์ ํ์ฉํ์ฌ ์ ์ ์ ๊ฒ์ํฉ๋๋ค.
- Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ๋ ์ง๋ 5์ฃผ ๋์๋ง์ ์ค๋ ์ท ๋ด๋ณด๋ด๊ธฐ ๋ฐ ๋์ด์ ์ง์ํฉ๋๋ค.
์ ์ ๋ณ๊ฒฝ์ฌํญ ๋ชจ๋ํฐ๋ง
Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ๋ ์ค์๊ฐ ์ ๋ฐ์ดํธ๋ฅผ ์ถ์ ํ๊ณ ์ด๋ฌํ ๋ณ๊ฒฝ์ฌํญ ๋ชจ๋ํฐ๋ง์ ์ง์ํฉ๋๋ค. ํผ๋๋ฅผ ๊ตฌ์ฑํ์ฌ ๋ฆฌ์์ค๊ฐ ์์ ๋ ๋๋ง๋ค ๊ตฌ์ฑ๋ Pub/Sub ์ฃผ์ ๋ชจ์์ ์๋ฆผ์ ๋ณด๋ผ ์ ์์ต๋๋ค. ๋ํ Cloud ์ ์ ์ธ๋ฒคํ ๋ฆฌ๋ ํผ๋์ ์กฐ๊ฑด ๊ตฌ์ฑ์ ์ง์ํ๋ฏ๋ก ํน์ ์ ์ ์ ํ์ ํน์ ๋ณ๊ฒฝ์ฌํญ์ ๋ชจ๋ํฐ๋งํ ์ ์์ต๋๋ค. ์ ์ ๋ณ๊ฒฝ์ ๋ํ ์ํฌํ๋ก๋ฅผ ํธ๋ฆฌ๊ฑฐํ๋ ๋ฐฉ๋ฒ์ Pub/Sub ๋ฌธ์๋ฅผ ์ฐธ์กฐํ์ธ์.
BigQuery๋ก ์ ์ ๋ด๋ณด๋ด๊ธฐ
๋ณด์ ๋น๋ฐ๊ณผ ๋ณด์ ๋น๋ฐ ๋ฒ์ ์ BigQuery๋ก ๋ด๋ณด๋ด๋ฉด ๋๊ท๋ชจ ๋ฐ์ดํฐ์ ๋ํด SQL๊ณผ ์ ์ฌํ ์ฟผ๋ฆฌ๋ฅผ ์คํํ๊ณ ์ ์ ์ ๋ํ ์๋ฏธ ์๋ ์ ๋ณด๋ฅผ ์์ฑํ ์ ์์ต๋๋ค. ์ ์ ์ ๋ด๋ณด๋ด๊ธฐ ์ ์ ๋ฐ์ดํฐ ์ธํธ ๋ฐ ์๋น์ค ๊ณ์ ์ด ์ฌ๋ฐ๋ฅด๊ฒ ๊ตฌ์ฑ๋์๋์ง ํ์ธํ์ธ์. ์ ์ ์ ๋ด๋ณด๋ด๋ ค๋ฉด ๋ค์ ๋ช ๋ น์ด๋ฅผ ์คํํฉ๋๋ค.
gcloud
$ gcloud asset export \ --content-type CONTENT_TYPE \ --project PROJECT_ID \ --snapshot-time SNAPSHOT_TIME \ --bigquery-table BIGQUERY_TABLE \ --output-bigquery-force
๊ฐ ํญ๋ชฉ์ ์๋ฏธ๋ ๋ค์๊ณผ ๊ฐ์ต๋๋ค.
- CONTENT_TYPE: ์ ์
์ฝํ
์ธ ์ ํ(
RESOURCE
)์ ๋๋ค. - PROJECT_ID: ๋ชจ๋ํฐ๋งํ ์ ์ ์ด ํฌํจ๋ ํ๋ก์ ํธ ID์ ๋๋ค.
- SNAPSHOT_TIME: ๋ฆฌ์์ค์ ์ค๋ ์ท์ ๋ง๋ค ์๊ฐ์ด๋ฉฐ, ํ์ฌ์ ์ง๋ 5์ฃผ ์ด๋ด์ ๋๋ค.
- BIGQUERY_TABLE:
projects/PROJECT_ID/datasets/DATASET_ID/tables/TABLE_NAME
ํ์์ผ๋ก ๋ฐ์ดํฐ๋ฅผ ๋ด๋ณด๋ผ ํ ์ด๋ธ์ ๋๋ค.
์์ธํ ๋ด์ฉ์ BigQuery๋ก ๋ด๋ณด๋ด๊ธฐ๋ฅผ ์ฐธ์กฐํ์ธ์.
์ํ ์ฟผ๋ฆฌ
์ง๋ 2์ฃผ ๋์ ์์ฑ๋ ๋ณด์ ๋น๋ฐ
์ง๋ 2์ฃผ ๋์ ์กฐ์ง์ ์ถ๊ฐ๋ ๋ณด์ ๋น๋ฐ๊ณผ ๊ทธ ์์ฑ์ ๊ฒ์ํฉ๋๋ค.
BigQuery
SELECT name, FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND DATE(JSON_VALUE(resource.data, '$.createTime')) > DATE_SUB(CURRENT_DATE(), INTERVAL 2 WEEK);
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.createTime>-P2W"
์๋์ผ๋ก ๋ณต์ ๋ ๋ณด์ ๋น๋ฐ
์๋์ผ๋ก ๋ณต์ ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ์ ์ฐพ์ต๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND JSON_EXTRACT(resource.data, '$.replication.automatic') IS NOT NULL;
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.replication.automatic != NULL"
์ง์ ๋ ๋ฆฌ์ ์ ๋ณต์ ๋ ๋ณด์ ๋น๋ฐ
us-central1
์ ๋ณต์ ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ์ ์ฐพ์ต๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE ( SELECT * FROM UNNEST(JSON_EXTRACT_ARRAY(resource.data, '$.replication.userManaged.replicas')) AS location WHERE JSON_VALUE(JSON_EXTRACT(location, '$.location')) = "us-central1" ) IS NOT NULL;
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.replication.userManaged.replicas.location=us-central1"
180์ผ ์ด์ ์ฌ์ฉ ์ค์ ๋ ๋ณด์ ๋น๋ฐ ๋ฒ์
180์ผ ์ด์ ์ ์์ฑ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ ๋ฒ์ ์ ๋์ดํฉ๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/SecretVersion' AND DATE(JSON_VALUE(resource.data, '$.createTime')) < DATE_SUB(CURRENT_DATE(), INTERVAL 180 DAY) AND JSON_VALUE(resource.data, '$.state') = "ENABLED";
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/SecretVersion' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.createTime < P6M AND resource.data.state=ENABLED"
CMEK๊ฐ ๊ตฌ์ฑ๋์ง ์์ ๋ณด์ ๋น๋ฐ
๊ณ ๊ฐ ๊ด๋ฆฌ์ ์ํธํ ํค(CMEK)๋ก ์ํธํ๋์ง ์์ ๋ชจ๋ ๋ณด์ ๋น๋ฐ(์๋ ๋ฐ ์ฌ์ฉ์ ๊ด๋ฆฌ)์ ๋์ดํฉ๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND ( JSON_VALUE(resource.data, "$.replication.automatic.customerManagedEncryption.kmsKeyName") IS NULL AND JSON_VALUE(resource.data, "$.replication.userManaged.replicas[0].customerManagedEncryption.kmsKeyName") IS NULL );
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.replication.userManaged.replicas.customerManagedEncryption = NULL OR resource.data.replication.automatic.customerManagedEncryption=NULL"
CMEK๊ฐ ๊ตฌ์ฑ๋ ๋ณด์ ๋น๋ฐ
CMEK๋ก ์ํธํ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ(์๋ ๋ฐ ์ฌ์ฉ์ ๊ด๋ฆฌ)์ ๋์ดํฉ๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND ( JSON_VALUE(resource.data, "$.replication.automatic.customerManagedEncryption.kmsKeyName") IS NOT NULL OR JSON_VALUE(resource.data, "$.replication.userManaged.replicas[0].customerManagedEncryption.kmsKeyName") IS NOT NULL );
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.replication.userManaged.replicas.customerManagedEncryption != NULL OR resource.data.replication.automatic.customerManagedEncryption!=NULL"
ํน์ CMEK๋ก ์ํธํ๋ ๋ณด์ ๋น๋ฐ
ํน์ CMEK๋ก ์ํธํ๋ ๋ณด์ ๋น๋ฐ ๋ฒ์ ์ธ ๋ณด์ ๋น๋ฐ์ ์ฐพ์ต๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND ( JSON_VALUE(resource.data, "$.replication.automatic.customerManagedEncryption.kmsKeyName") = KMS_KEY_NAME OR JSON_VALUE(resource.data, "$.replication.userManaged.replicas[0].customerManagedEncryption.kmsKeyName") = KMS_KEY_NAME );
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.replication.userManaged.replicas.customerManagedEncryption.kmsKeyName=KMS_KEY_NAME"
CMEK๊ฐ ๊ตฌ์ฑ๋์ง ์์ ๋ณด์ ๋น๋ฐ ๋ฒ์
CMEK๋ก ์ํธํ๋์ง ์์ ์ฌ์ฉ ์ค์ ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ ๋ฒ์ ์ ์ฐพ์ต๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/SecretVersion' AND ( JSON_VALUE(resource.data, "$.replicationStatus.automatic.customerManagedEncryption.kmsKeyVersionName") IS NULL AND JSON_VALUE(resource.data, "$.replicationStatus.userManaged.replicas[0].customerManagedEncryption.kmsKeyVersionName") IS NULL ) AND JSON_VALUE(resource.data, "$.state") = "ENABLED";
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/SecretVersion' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="(resource.data.replicationStatus.userManaged.replicas.customerManagedEncryption = NULL OR resource.data.replicationStatus.automatic.customerManagedEncryption=NULL) AND resource.data.state=ENABLED"
ํน์ CMEK๋ก ์ํธํ๋ ๋ณด์ ๋น๋ฐ ๋ฒ์
ํน์ CMEK ๋ฒ์ ์ผ๋ก ์ํธํ๋ ๋ชจ๋ ์ฌ์ฉ ์ค์ ๋ ๋ณด์ ๋น๋ฐ ๋ฒ์ ์ ๋์ดํฉ๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/SecretVersion' AND ( JSON_VALUE(resource.data, "$.replicationStatus.automatic.customerManagedEncryption.kmsKeyVersionName") = KMS_KEY_VERSION_NAME OR JSON_VALUE(resource.data, "$.replicationStatus.userManaged.replicas[0].customerManagedEncryption.kmsKeyVersionName") = KMS_KEY_VERSION_NAME ) AND JSON_VALUE(resource.data,"$.state")="ENABLED";
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/SecretVersion' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.replicationStatus.userManaged.replicas.customerManagedEncryption.kmsKeyVersionName=$FULL_KMS_KEY_VERSION_RESOURCE_NAME AND resource.data.status=ENABLED"
์ํ์ด ๊ตฌ์ฑ๋์ง ์์ ๋ณด์ ๋น๋ฐ
์ํ ์ผ์ ์ด ์๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ์ ์ฐพ์ต๋๋ค.
BigQuery
SELECT name FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND JSON_EXTRACT(resource.data, '$.rotation') IS NULL;
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.rotation=NULL"
ํน์ ์ํ ๊ธฐ๊ฐ์ด ์๋ ๋ณด์ ๋น๋ฐ
90์ผ ๋ฏธ๋ง๋ง๋ค ํ ๋ฒ ์ํํ๋๋ก ์์ฝ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ์ ์ฐพ์ต๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE CAST( TRIM( JSON_VALUE(JSON_EXTRACT(resource.data, "$.rotation.rotationPeriod")),"s") AS INT64) < 86400 * 90 #Rotation period in seconds (86400s in 1 day * 90 days)
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ ROTATION_PERIOD_SECONDS=$((90 * 24 * 60 * 60)) $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.rotation != null AND resource.data.rotation.rotationPeriod < ${ROTATION_PERIOD_SECONDS}s"
ํฅํ 30์ผ ์ด๋ด์ ๋ง๋ฃ๋๋ ๋ณด์ ๋น๋ฐ
ํฅํ 30์ผ ์ด๋ด์ ๋ง๋ฃ๋๋ ๋ณด์ ๋น๋ฐ์ ๋์ดํฉ๋๋ค.
BigQuery
SELECT * FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND DATE(JSON_VALUE(resource.data, '$.expireTime')) < DATE_ADD(CURRENT_DATE(), INTERVAL 30 DAY);
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.expireTime < PD30"
Pub/Sub ์ฃผ์ ๊ฐ ๊ตฌ์ฑ๋ ๋ณด์ ๋น๋ฐ
Pub/Sub ์ฃผ์ ๊ฐ ํ๋ ์ด์ ๊ตฌ์ฑ๋ ๋ชจ๋ ๋ณด์ ๋น๋ฐ์ ๋์ดํฉ๋๋ค.
BigQuery
SELECT name, ARRAY_LENGTH(JSON_EXTRACT_ARRAY(resource.data, '$.topics')) AS topics_count, FROM PROJECT_ID.DATASET_ID.TABLE_NAME WHERE asset_type='secretmanager.googleapis.com/Secret' AND ARRAY_LENGTH(JSON_EXTRACT_ARRAY(resource.data, '$.topics')) > 0
gcloud
$ NOW=$(TZ=GMT date +"%Y-%m-%dT%H:%M:%SZ") $ gcloud asset list --project=PROJECT_ID \ --asset-types='secretmanager.googleapis.com/Secret' \ --snapshot-time=$NOW \ --content-type='resource' \ --filter="resource.data.topics !=NULL"
๋ค์ ๋จ๊ณ
- ๋ค๋ฅธ ์ ํ์์ Secret Manager ์ฌ์ฉ์ ๋ํด ์์ธํ ์์๋ณด๊ธฐ