Skip to content
This repository was archived by the owner on Oct 13, 2023. It is now read-only.

Commit 2738864

Browse files
committed
save credentials to rotate repository
1 parent 94765b2 commit 2738864

File tree

2 files changed

+56
-6
lines changed

2 files changed

+56
-6
lines changed

README.md

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,11 @@ Version for rotate organization secret, cloned from [kneemaa/github-action-rotat
3535

3636
#### OWNER_ORGANIZATION
3737
- Required: ***True***
38-
- Description: The owner and repository name. For example, octocat. If being ran in the repo being updated, you can use `${{github.repository_owner}}`
38+
- Description: The owner repository name. For example, octocat. If being ran in the repo being updated, you can use `${{github.repository_owner}}`
39+
40+
#### OWNER_REPOSITORY
41+
- Required: ***True***
42+
- Description: The repository name. For example, octocat. If being ran in the repo being updated, you can use `${{github.repository}}`
3943

4044
#### GITHUB_ACCESS_KEY_NAME
4145
- Required: ***False***
@@ -71,6 +75,7 @@ jobs:
7175
IAM_USERNAME: 'iam-user-name'
7276
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
7377
OWNER_ORGANIZATION: ${{ github.repository_owner }}
78+
OWNER_REPOSITORY: {{ github.repository }}
7479
```
7580

7681
## Adding Slack notification on failure only
@@ -94,6 +99,7 @@ jobs:
9499
IAM_USERNAME: 'iam-user-name'
95100
PERSONAL_ACCESS_TOKEN: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
96101
OWNER_ORGANIZATION: ${{ github.repository_owner }}
102+
OWNER_REPOSITORY: {{ github.repository }}
97103
98104
- name: Send Slack Status
99105
if: failure()

rotate_keys.py

Lines changed: 49 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ def main_function():
2525
iam_username = os.environ['IAM_USERNAME'] if 'IAM_USERNAME' in os.environ else who_am_i()
2626
github_token = os.environ['PERSONAL_ACCESS_TOKEN']
2727
owner_organization = os.environ['OWNER_ORGANIZATION']
28+
owner_repository = os.environ['OWNER_REPOSITORY']
2829

2930
list_ret = iam.list_access_keys(UserName=iam_username)
3031
starting_num_keys = len(list_ret["AccessKeyMetadata"])
@@ -43,15 +44,18 @@ def main_function():
4344
(new_access_key, new_secret_key) = create_new_keys(iam_username)
4445

4546
#get org pub key info
46-
(public_key, pub_key_id) = get_pub_key(owner_organization, github_token)
47+
(dependabot_public_key, dependabot_pub_key_id) = get_dependabot_pub_key(owner_organization, github_token)
48+
(repo_public_key, repo_pub_key_id) = get_repo_pub_key(owner_repository, github_token)
4749

4850
#encrypt the secrets
4951
encrypted_access_key = encrypt(public_key,new_access_key)
5052
encrypted_secret_key = encrypt(public_key,new_secret_key)
5153

5254
#upload secrets
53-
upload_secret(owner_organization,access_key_name,encrypted_access_key,pub_key_id,github_token)
54-
upload_secret(owner_organization,secret_key_name,encrypted_secret_key,pub_key_id,github_token)
55+
upload_repo_secret(owner_repository,access_key_name,encrypted_access_key,repo_pub_key_id,github_token)
56+
upload_repo_secret(owner_repository,secret_key_name,encrypted_secret_key,repo_pub_key_id,github_token)
57+
upload_dependabot_secret(owner_organization,access_key_name,encrypted_access_key,dependabot_pub_key_id,github_token)
58+
upload_dependabot_secret(owner_organization,secret_key_name,encrypted_secret_key,dependabot_pub_key_id,github_token)
5559

5660
#delete old keys
5761
delete_old_keys(iam_username, current_access_id)
@@ -110,7 +114,7 @@ def encrypt(public_key: str, secret_value: str) -> str:
110114
encrypted = sealed_box.encrypt(secret_value.encode("utf-8"))
111115
return b64encode(encrypted).decode("utf-8")
112116

113-
def get_pub_key(owner_org, github_token):
117+
def get_dependabot_pub_key(owner_org, github_token):
114118
# get public key for encrypting
115119
pub_key_ret = requests.get(
116120
f'https://api.github.com/orgs/{owner_org}/dependabot/secrets/public-key',
@@ -130,7 +134,7 @@ def get_pub_key(owner_org, github_token):
130134

131135
return (public_key, public_key_id)
132136

133-
def upload_secret(owner_org,key_name,encrypted_value,pub_key_id,github_token):
137+
def upload_dependabot_secret(owner_org,key_name,encrypted_value,pub_key_id,github_token):
134138
#upload encrypted access key
135139
updated_secret = requests.put(
136140
f'https://api.github.com/orgs/{owner_org}/dependabot/secrets/{key_name}',
@@ -149,5 +153,45 @@ def upload_secret(owner_org,key_name,encrypted_value,pub_key_id,github_token):
149153
sys.exit(1)
150154
print(f'Updated {key_name} in {owner_org}')
151155

156+
# Update Repository Secret, because: Gets a single organization secret without revealing its encrypted value.
157+
# https://docs.github.com/en/rest/dependabot/secrets#get-an-organization-secret
158+
def get_repo_pub_key(owner_repo, github_token):
159+
# get public key for encrypting
160+
pub_key_ret = requests.get(
161+
f'https://api.github.com/repos/{owner_repo}/actions/secrets/public-key',
162+
headers={'Authorization': f"token {github_token}"}
163+
)
164+
165+
if not pub_key_ret.status_code == requests.codes.ok:
166+
raise Exception(f"github public key request failed, status code: {pub_key_ret.status_code}, body: {pub_key_ret.text}, vars: {owner_repo} {github_token}")
167+
sys.exit(1)
168+
169+
#convert to json
170+
public_key_info = pub_key_ret.json()
171+
172+
#extract values
173+
public_key = public_key_info['key']
174+
public_key_id = public_key_info['key_id']
175+
176+
return (public_key, public_key_id)
177+
178+
def upload_repo_secret(owner_repo,key_name,encrypted_value,pub_key_id,github_token):
179+
#upload encrypted access key
180+
updated_secret = requests.put(
181+
f'https://api.github.com/repos/{owner_repo}/actions/secrets/{key_name}',
182+
json={
183+
'encrypted_value': encrypted_value,
184+
'key_id': pub_key_id
185+
},
186+
headers={'Authorization': f"token {github_token}"}
187+
)
188+
# status codes github says are valid
189+
good_status_codes = [204,201]
190+
191+
if updated_secret.status_code not in good_status_codes:
192+
print(f'Got status code: {updated_secret.status_code} on updating {key_name} in {owner_repo}')
193+
sys.exit(1)
194+
print(f'Updated {key_name} in {owner_repo}')
195+
152196
# run everything
153197
main_function()

0 commit comments

Comments
 (0)