Skip to content

Commit 921f8d9

Browse files
authored
Merge pull request #3 from 02ez/copilot/fix-4f8f2aa5-4a54-438f-89e7-b4cc01fe7225
Devcontainer Hardening with Port Visibility Automation
2 parents b307022 + 38433d4 commit 921f8d9

File tree

10 files changed

+365
-6
lines changed

10 files changed

+365
-6
lines changed

content/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ redirect_from:
1010
- /codespaces/setting-up-your-project-for-codespaces/setting-up-your-project-for-codespaces
1111
children:
1212
- /introduction-to-dev-containers
13+
- /securing-port-forwarding-in-dev-containers
1314
- /setting-up-your-nodejs-project-for-codespaces
1415
- /setting-up-your-dotnet-project-for-codespaces
1516
- /setting-up-your-java-project-for-codespaces

content/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/introduction-to-dev-containers.md

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,17 @@ For information about how to choose your preferred dev container configuration w
5151

5252
{% data reusables.codespaces.more-info-devcontainer %}
5353

54+
#### Security considerations for dev containers
55+
56+
When configuring your dev container, consider security implications, especially for port forwarding and network access:
57+
58+
* **Port visibility**: By default, forwarded ports are private to you. Consider whether ports need to be accessible to your organization or publicly accessible
59+
* **Automated port configuration**: Use `postAttachCommand` with the {% data variables.product.prodname_cli %} to automatically apply consistent port visibility settings
60+
* **Organization policies**: Work within your organization's port visibility policies if they have restrictions in place
61+
* **Minimal port exposure**: Only forward ports that are necessary for development and testing
62+
63+
For detailed guidance on secure port forwarding configurations, see [AUTOTITLE](/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/securing-port-forwarding-in-dev-containers).
64+
5465
#### How to use the devcontainer.json
5566

5667
It's useful to think of the `devcontainer.json` file as providing "customization" rather than "personalization." You should only include things that everyone working on your codebase needs as standard elements of the development environment, not things that are personal preferences. Things like linters are good to standardize on, and to require everyone to have installed, so they're good to include in your `devcontainer.json` file. Things like user interface decorators or themes are personal choices that should not be put in the `devcontainer.json` file.
@@ -230,4 +241,5 @@ Changes to a configuration will be applied the next time you create a codespace.
230241

231242
## Further reading
232243

244+
* [AUTOTITLE](/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/securing-port-forwarding-in-dev-containers)
233245
* [AUTOTITLE](/codespaces/prebuilding-your-codespaces)
Lines changed: 160 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,160 @@
1+
---
2+
title: Securing port forwarding in dev containers
3+
shortTitle: Secure port forwarding
4+
intro: 'Learn how to configure secure port forwarding settings in your dev container configuration to control port visibility and automate security settings.'
5+
permissions: People with write permissions to a repository can create or edit the codespace configuration.
6+
versions:
7+
fpt: '*'
8+
ghec: '*'
9+
type: how_to
10+
topics:
11+
- Codespaces
12+
- Set up
13+
- Security
14+
---
15+
16+
## About port forwarding security in dev containers
17+
18+
When you configure a dev container for {% data variables.product.prodname_github_codespaces %}, you can control how ports are forwarded and their visibility settings. This is important for security, especially when working with sensitive applications or in organizations with strict access policies.
19+
20+
By default, {% data variables.product.prodname_github_codespaces %} forwards ports privately, meaning only you can access them. However, you can configure your dev container to automatically apply specific visibility settings when the codespace starts.
21+
22+
## Configuring port forwarding with security in mind
23+
24+
You can configure port forwarding in your dev container using several properties, each serving different security purposes. The key properties for secure port forwarding are `forwardPorts`, `portsAttributes`, and `postAttachCommand`.
25+
26+
### Using forwardPorts with portsAttributes
27+
28+
The most basic approach is to specify which ports should be forwarded and configure their attributes:
29+
30+
```jsonc
31+
{
32+
"name": "My Secure Dev Container",
33+
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
34+
35+
"forwardPorts": [3000, 8080, 8443],
36+
37+
"portsAttributes": {
38+
"3000": {
39+
"label": "Application Server",
40+
"protocol": "http"
41+
},
42+
"8080": {
43+
"label": "API Server",
44+
"protocol": "http"
45+
},
46+
"8443": {
47+
"label": "Secure API",
48+
"protocol": "https"
49+
}
50+
}
51+
}
52+
```
53+
54+
{% data reusables.codespaces.portsattributes-configuration %}
55+
56+
### Automating port visibility settings
57+
58+
You can automate port visibility settings using the `postAttachCommand` property. This ensures consistent security settings every time someone connects to the codespace:
59+
60+
```jsonc
61+
{
62+
"name": "My Secure Dev Container",
63+
"image": "mcr.microsoft.com/devcontainers/base:bullseye",
64+
65+
"forwardPorts": [3000, 8080],
66+
67+
"portsAttributes": {
68+
"3000": {
69+
"label": "Dev Server (Private)"
70+
},
71+
"8080": {
72+
"label": "API Server (Team Only)"
73+
}
74+
},
75+
76+
"features": {
77+
"ghcr.io/devcontainers/features/github-cli:1": {}
78+
},
79+
80+
"postAttachCommand": "gh cs ports visibility 3000:private 8080:org -c \"$CODESPACE_NAME\""
81+
}
82+
```
83+
84+
{% data reusables.codespaces.port-visibility-automation %}
85+
86+
## Security best practices
87+
88+
{% data reusables.codespaces.port-security-best-practices %}
89+
90+
## Working with organization policies
91+
92+
Organization administrators can set policies that restrict which port visibility options are available. For more information, see [AUTOTITLE](/codespaces/managing-codespaces-for-your-organization/restricting-the-visibility-of-forwarded-ports).
93+
94+
If your organization has port visibility restrictions in place, make sure your dev container automation commands comply with these policies. For example, if your organization disallows public port forwarding, don't use `public` in your `postAttachCommand`.
95+
96+
## Example configurations
97+
98+
The following examples demonstrate different security approaches for common development scenarios.
99+
100+
### Development environment with private ports
101+
102+
```jsonc
103+
{
104+
"name": "Private Development Environment",
105+
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18",
106+
107+
"forwardPorts": [3000, 3001],
108+
109+
"portsAttributes": {
110+
"3000": {
111+
"label": "Web Server (Private)",
112+
"protocol": "http"
113+
},
114+
"3001": {
115+
"label": "API Server (Private)",
116+
"protocol": "http"
117+
}
118+
},
119+
120+
"features": {
121+
"ghcr.io/devcontainers/features/github-cli:1": {}
122+
},
123+
124+
"postAttachCommand": "gh cs ports visibility 3000:private 3001:private -c \"$CODESPACE_NAME\""
125+
}
126+
```
127+
128+
### Team collaboration with organization-only ports
129+
130+
```jsonc
131+
{
132+
"name": "Team Collaboration Environment",
133+
"image": "mcr.microsoft.com/devcontainers/python:3-bullseye",
134+
135+
"forwardPorts": [5000, 8000],
136+
137+
"portsAttributes": {
138+
"5000": {
139+
"label": "Flask App (Team)",
140+
"protocol": "http"
141+
},
142+
"8000": {
143+
"label": "Django Admin (Team)",
144+
"protocol": "https"
145+
}
146+
},
147+
148+
"features": {
149+
"ghcr.io/devcontainers/features/github-cli:1": {}
150+
},
151+
152+
"postAttachCommand": "gh cs ports visibility 5000:org 8000:org -c \"$CODESPACE_NAME\""
153+
}
154+
```
155+
156+
## Further reading
157+
158+
* [AUTOTITLE](/codespaces/developing-in-a-codespace/forwarding-ports-in-your-codespace)
159+
* [AUTOTITLE](/codespaces/managing-codespaces-for-your-organization/restricting-the-visibility-of-forwarded-ports)
160+
* {% data reusables.codespaces.more-info-devcontainer %}

content/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/setting-up-your-nodejs-project-for-codespaces.md

Lines changed: 78 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -147,9 +147,82 @@ With your dev container configuration added and a basic understanding of what ev
147147

148148
After the dev container is rebuilt, and your codespace becomes available again, the `postCreateCommand` will have been run, installing npm, and the "Code Spell Checker" extension will be available for use.
149149

150-
## Step 4: Run your application
150+
## Step 4: Configure port forwarding and security
151151

152-
In the previous section, you used the `postCreateCommand` to install a set of packages via the `npm install` command. With the dependencies now installed, you can run the application.
152+
Node.js applications typically run on port 3000. You can configure your dev container to automatically forward this port and set appropriate security settings.
153+
154+
1. Add port forwarding configuration by uncommenting and modifying the `forwardPorts` property:
155+
156+
```jsonc copy
157+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
158+
"forwardPorts": [3000],
159+
```
160+
161+
1. Add port attributes to label your forwarded port:
162+
163+
```jsonc copy
164+
"portsAttributes": {
165+
"3000": {
166+
"label": "Node.js App"
167+
}
168+
},
169+
```
170+
171+
1. For enhanced security, you can add a `postAttachCommand` to automatically set port visibility. Add the {% data variables.product.prodname_cli %} feature first:
172+
173+
```jsonc copy
174+
"features": {
175+
"ghcr.io/devcontainers-contrib/features/jshint:2": {},
176+
"ghcr.io/devcontainers/features/github-cli:1": {}
177+
},
178+
```
179+
180+
1. Then add the `postAttachCommand` to control port visibility:
181+
182+
```jsonc copy
183+
// Automatically set port visibility when attaching to the codespace
184+
"postAttachCommand": "gh cs ports visibility 3000:private -c \"$CODESPACE_NAME\""
185+
```
186+
187+
Your updated `devcontainer.json` should look similar to this:
188+
189+
```jsonc
190+
{
191+
"name": "Node.js",
192+
"image": "mcr.microsoft.com/devcontainers/javascript-node:0-18-bullseye",
193+
"features": {
194+
"ghcr.io/devcontainers-contrib/features/jshint:2": {},
195+
"ghcr.io/devcontainers/features/github-cli:1": {}
196+
},
197+
198+
"forwardPorts": [3000],
199+
200+
"portsAttributes": {
201+
"3000": {
202+
"label": "Node.js App"
203+
}
204+
},
205+
206+
"postCreateCommand": "npm install",
207+
208+
"postAttachCommand": "gh cs ports visibility 3000:private -c \"$CODESPACE_NAME\"",
209+
210+
"customizations": {
211+
"vscode": {
212+
"extensions": [
213+
"streetsidesoftware.code-spell-checker"
214+
]
215+
}
216+
}
217+
}
218+
```
219+
220+
{% data reusables.codespaces.save-changes %}
221+
{% data reusables.codespaces.rebuild-command %}
222+
223+
## Step 5: Run your application
224+
225+
In the previous section, you configured port forwarding for your Node.js application. Now you can run the application and see it in action.
153226

154227
1. In the Terminal of your codespace, enter `npm start`.
155228

@@ -159,12 +232,14 @@ In the previous section, you used the `postCreateCommand` to install a set of pa
159232

160233
![Screenshot of the port forwarding message, reading "Your application running on port 3000 is available." The "Open in Browser" button is also shown.](/assets/images/help/codespaces/codespaces-port3000-toast.png)
161234

162-
## Step 5: Commit your changes
235+
## Step 6: Commit your changes
163236

164237
{% data reusables.codespaces.committing-link-to-procedure %}
165238

166239
## Next steps
167240

168241
You should now be able to add a custom dev container configuration to your own Node.js, JavaScript, or TypeScript project.
169242

243+
For more advanced port security configurations, see [AUTOTITLE](/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/securing-port-forwarding-in-dev-containers).
244+
170245
{% data reusables.codespaces.next-steps-adding-devcontainer %}

content/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/setting-up-your-python-project-for-codespaces.md

Lines changed: 49 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -87,6 +87,7 @@ The default development container, or "dev container," for {% data variables.pro
8787
## Step 3: Modify your devcontainer.json file
8888

8989
With your dev container configuration added and a basic understanding of what everything does, you can now make changes to customize your environment further. In this example, you'll add properties that will:
90+
* Configure port forwarding for the Flask application with security settings.
9091
* Install a package required by the application.
9192
* Install a {% data variables.product.prodname_vscode_shortname %} extension in this codespace.
9293

@@ -101,13 +102,46 @@ With your dev container configuration added and a basic understanding of what ev
101102
// "features": {},
102103
```
103104

105+
1. Uncomment the `forwardPorts` property and configure it for Flask (port 5000):
106+
107+
```jsonc copy
108+
// Use 'forwardPorts' to make a list of ports inside the container available locally.
109+
"forwardPorts": [5000],
110+
```
111+
112+
1. Add port attributes and security configuration:
113+
114+
```jsonc copy
115+
"portsAttributes": {
116+
"5000": {
117+
"label": "Flask Application"
118+
}
119+
},
120+
```
121+
122+
1. Add the {% data variables.product.prodname_cli %} feature for port visibility automation:
123+
124+
```jsonc copy
125+
"features": {
126+
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {},
127+
"ghcr.io/devcontainers/features/github-cli:1": {}
128+
},
129+
```
130+
104131
1. Uncomment the `postCreateCommand` property.
105132

106133
```jsonc copy
107134
// Use 'postCreateCommand' to run commands after the container is created.
108135
"postCreateCommand": "pip3 install --user -r requirements.txt",
109136
```
110137

138+
1. Add automated port visibility configuration:
139+
140+
```jsonc copy
141+
// Automatically set port visibility when attaching to the codespace
142+
"postAttachCommand": "gh cs ports visibility 5000:private -c \"$CODESPACE_NAME\""
143+
```
144+
111145
{% data reusables.codespaces.add-extension-to-devcontainer %}
112146

113147
```jsonc
@@ -118,14 +152,24 @@ With your dev container configuration added and a basic understanding of what ev
118152
// Or use a Dockerfile or Docker Compose file. More info: https://containers.dev/guide/dockerfile
119153
"image": "mcr.microsoft.com/devcontainers/python:0-3.11-bullseye",
120154
"features": {
121-
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {}
155+
"ghcr.io/devcontainers-contrib/features/coverage-py:2": {},
156+
"ghcr.io/devcontainers/features/github-cli:1": {}
122157
},
123158

124159
// Use 'forwardPorts' to make a list of ports inside the container available locally.
125-
// "forwardPorts": [],
160+
"forwardPorts": [5000],
161+
162+
"portsAttributes": {
163+
"5000": {
164+
"label": "Flask Application"
165+
}
166+
},
126167

127168
// Use 'postCreateCommand' to run commands after the container is created.
128169
"postCreateCommand": "pip3 install --user -r requirements.txt",
170+
171+
// Automatically set port visibility when attaching to the codespace
172+
"postAttachCommand": "gh cs ports visibility 5000:private -c \"$CODESPACE_NAME\"",
129173

130174
// Configure tool-specific properties.
131175
"customizations": {
@@ -147,7 +191,7 @@ With your dev container configuration added and a basic understanding of what ev
147191
{% data reusables.codespaces.rebuild-command %}
148192
{% data reusables.codespaces.rebuild-reason %}
149193

150-
After the dev container is rebuilt, and your codespace becomes available again, the `postCreateCommand` will have been run, installing the package listed in the `requirements.txt` file, and the "Code Spell Checker" extension will be available for use.
194+
After the dev container is rebuilt, and your codespace becomes available again, the `postCreateCommand` will have been run, installing the package listed in the `requirements.txt` file, the `postAttachCommand` will have configured the port visibility settings, and the "Code Spell Checker" extension will be available for use.
151195

152196
## Step 4: Run your application
153197

@@ -169,4 +213,6 @@ In the previous section, you used the `postCreateCommand` to install a package f
169213

170214
You should now be able to add a custom dev container configuration to your own Python project.
171215

216+
For more advanced port security configurations, see [AUTOTITLE](/codespaces/setting-up-your-project-for-codespaces/adding-a-dev-container-configuration/securing-port-forwarding-in-dev-containers).
217+
172218
{% data reusables.codespaces.next-steps-adding-devcontainer %}

data/reusables/codespaces/devcontainer-properties-1.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,4 @@
22
* **image:** The name of an image in a container registry ([DockerHub](https://hub.docker.com/), [{% data variables.product.prodname_dotcom %} {% data variables.product.prodname_container_registry %}](/packages/learn-github-packages/introduction-to-github-packages), or [Azure Container Registry](https://azure.microsoft.com/services/container-registry/)) that will be used to create the dev container for the codespace.
33
* **features:** A list of one or more objects, each of which references one of the available dev container features. Features are self-contained, shareable units of installation code and development container configuration. They provide an easy way to add more tooling, runtime, or library features to your development container. You can add features either within {% data variables.product.prodname_vscode_shortname %} or in the `devcontainer.json` editor on {% data variables.product.github %}. For more information, click either the **{% data variables.product.prodname_vscode %}** or **Web browser** tab in [AUTOTITLE](/codespaces/setting-up-your-project-for-codespaces/configuring-dev-containers/adding-features-to-a-devcontainer-file?tool=webui).
44
* **forwardPorts:** Any ports listed here will be forwarded automatically. For more information, see [AUTOTITLE](/codespaces/developing-in-codespaces/forwarding-ports-in-your-codespace).
5+
* **portsAttributes:** This property maps specified ports to configuration options such as labels and protocols. {% data reusables.codespaces.portsattributes-configuration %}

0 commit comments

Comments
 (0)