Skip to content

Commit 73f5c99

Browse files
authored
Merge pull request #153 from dscho/limit-access-to-actor-auto
Default to using public key authentication (if any public SSH key is registered)
2 parents 1005f9c + 4d571a0 commit 73f5c99

File tree

4 files changed

+41
-17
lines changed

4 files changed

+41
-17
lines changed

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -127,7 +127,7 @@ jobs:
127127

128128
## Use registered public SSH key(s)
129129

130-
By default anybody can connect to the tmate session. You can opt-in to install the public SSH keys [that you have registered with your GitHub profile](https://docs.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account).
130+
If [you have registered one or more public SSH keys with your GitHub profile](https://docs.github.com/en/github/authenticating-to-github/adding-a-new-ssh-key-to-your-github-account), tmate will be started such that only those keys are authorized to connect, otherwise anybody can connect to the tmate session. If you want to require a public SSH key to be installed with the tmate session, no matter whether the user who started the workflow has registered any in their GitHub profile, you will need to configure the setting `limit-access-to-actor` to `true`, like so:
131131

132132
```yaml
133133
name: CI

action.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,9 +16,9 @@ inputs:
1616
required: false
1717
default: 'true'
1818
limit-access-to-actor:
19-
description: 'If only the public SSH keys of the user triggering the workflow should be authorized'
19+
description: 'Whether to authorize only the public SSH keys of the user triggering the workflow (defaults to true if the GitHub profile of the user has a public SSH key)'
2020
required: false
21-
default: 'false'
21+
default: 'auto'
2222
tmate-server-host:
2323
description: 'The hostname for your tmate server (e.g. ssh.example.org)'
2424
required: false

lib/index.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12630,7 +12630,10 @@ async function run() {
1263012630
}
1263112631

1263212632
let newSessionExtra = ""
12633-
if (core.getInput("limit-access-to-actor") === "true") {
12633+
let tmateSSHDashI = ""
12634+
let publicSSHKeysWarning = ""
12635+
const limitAccessToActor = core.getInput("limit-access-to-actor")
12636+
if (limitAccessToActor === "true" || limitAccessToActor === "auto") {
1263412637
const { actor, apiUrl } = github.context
1263512638
const auth = core.getInput('github-token')
1263612639
const octokit = new dist_node/* Octokit */.v({ auth, baseUrl: apiUrl })
@@ -12639,13 +12642,16 @@ async function run() {
1263912642
username: actor
1264012643
})
1264112644
if (keys.data.length === 0) {
12642-
throw new Error(`No public SSH keys registered with ${actor}'s GitHub profile`)
12645+
if (limitAccessToActor === "auto") publicSSHKeysWarning = `No public SSH keys found for ${actor}; continuing without them even if it is less secure (please consider adding an SSH key, see https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)`
12646+
else throw new Error(`No public SSH keys registered with ${actor}'s GitHub profile`)
12647+
} else {
12648+
const sshPath = external_path_default().join(external_os_default().homedir(), ".ssh")
12649+
await external_fs_default().promises.mkdir(sshPath, { recursive: true })
12650+
const authorizedKeysPath = external_path_default().join(sshPath, "authorized_keys")
12651+
await external_fs_default().promises.writeFile(authorizedKeysPath, keys.data.map(e => e.key).join('\n'))
12652+
newSessionExtra = `-a "${authorizedKeysPath}"`
12653+
tmateSSHDashI = "ssh -i <path-to-private-SSH-key>"
1264312654
}
12644-
const sshPath = external_path_default().join(external_os_default().homedir(), ".ssh")
12645-
await external_fs_default().promises.mkdir(sshPath, { recursive: true })
12646-
const authorizedKeysPath = external_path_default().join(sshPath, "authorized_keys")
12647-
await external_fs_default().promises.writeFile(authorizedKeysPath, keys.data.map(e => e.key).join('\n'))
12648-
newSessionExtra = `-a "${authorizedKeysPath}"`
1264912655
}
1265012656

1265112657
const tmate = `${tmateExecutable} -S /tmp/tmate.sock`;
@@ -12684,10 +12690,16 @@ async function run() {
1268412690

1268512691
core.debug("Entering main loop")
1268612692
while (true) {
12693+
if (publicSSHKeysWarning) {
12694+
core.warning(publicSSHKeysWarning)
12695+
}
1268712696
if (tmateWeb) {
1268812697
core.info(`Web shell: ${tmateWeb}`);
1268912698
}
1269012699
core.info(`SSH: ${tmateSSH}`);
12700+
if (tmateSSHDashI) {
12701+
core.info(`or: ${tmateSSH.replace(/^ssh/, tmateSSHDashI)}`)
12702+
}
1269112703

1269212704
if (continueFileExists()) {
1269312705
core.info("Exiting debugging session because the continue file was created")

src/index.js

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,10 @@ export async function run() {
7979
}
8080

8181
let newSessionExtra = ""
82-
if (core.getInput("limit-access-to-actor") === "true") {
82+
let tmateSSHDashI = ""
83+
let publicSSHKeysWarning = ""
84+
const limitAccessToActor = core.getInput("limit-access-to-actor")
85+
if (limitAccessToActor === "true" || limitAccessToActor === "auto") {
8386
const { actor, apiUrl } = github.context
8487
const auth = core.getInput('github-token')
8588
const octokit = new Octokit({ auth, baseUrl: apiUrl })
@@ -88,13 +91,16 @@ export async function run() {
8891
username: actor
8992
})
9093
if (keys.data.length === 0) {
91-
throw new Error(`No public SSH keys registered with ${actor}'s GitHub profile`)
94+
if (limitAccessToActor === "auto") publicSSHKeysWarning = `No public SSH keys found for ${actor}; continuing without them even if it is less secure (please consider adding an SSH key, see https://docs.github.com/en/authentication/connecting-to-github-with-ssh/adding-a-new-ssh-key-to-your-github-account)`
95+
else throw new Error(`No public SSH keys registered with ${actor}'s GitHub profile`)
96+
} else {
97+
const sshPath = path.join(os.homedir(), ".ssh")
98+
await fs.promises.mkdir(sshPath, { recursive: true })
99+
const authorizedKeysPath = path.join(sshPath, "authorized_keys")
100+
await fs.promises.writeFile(authorizedKeysPath, keys.data.map(e => e.key).join('\n'))
101+
newSessionExtra = `-a "${authorizedKeysPath}"`
102+
tmateSSHDashI = "ssh -i <path-to-private-SSH-key>"
92103
}
93-
const sshPath = path.join(os.homedir(), ".ssh")
94-
await fs.promises.mkdir(sshPath, { recursive: true })
95-
const authorizedKeysPath = path.join(sshPath, "authorized_keys")
96-
await fs.promises.writeFile(authorizedKeysPath, keys.data.map(e => e.key).join('\n'))
97-
newSessionExtra = `-a "${authorizedKeysPath}"`
98104
}
99105

100106
const tmate = `${tmateExecutable} -S /tmp/tmate.sock`;
@@ -133,10 +139,16 @@ export async function run() {
133139

134140
core.debug("Entering main loop")
135141
while (true) {
142+
if (publicSSHKeysWarning) {
143+
core.warning(publicSSHKeysWarning)
144+
}
136145
if (tmateWeb) {
137146
core.info(`Web shell: ${tmateWeb}`);
138147
}
139148
core.info(`SSH: ${tmateSSH}`);
149+
if (tmateSSHDashI) {
150+
core.info(`or: ${tmateSSH.replace(/^ssh/, tmateSSHDashI)}`)
151+
}
140152

141153
if (continueFileExists()) {
142154
core.info("Exiting debugging session because the continue file was created")

0 commit comments

Comments
 (0)