Skip to content

Commit cb31eb2

Browse files
authored
Merge pull request #9 from GitHubSecurityLab/container-reg-updates
feat: Container class updates
2 parents 8524a48 + de08ad2 commit cb31eb2

File tree

5 files changed

+284
-18
lines changed

5 files changed

+284
-18
lines changed

ql/lib/codeql/bicep/frameworks/Microsoft/Containers.qll

Lines changed: 208 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ private import bicep
22

33
module Containers {
44
/**
5-
* Represents a Microsoft.ContainerApp/containerApps resource.
5+
* Represents a Microsoft.ContainerApp/containerApps resource (2025-02-02-preview).
66
* See: https://learn.microsoft.com/en-us/azure/templates/microsoft.app/containerapps
77
*/
88
class ContainerResource extends Resource {
@@ -11,6 +11,31 @@ module Containers {
1111
*/
1212
ContainerResource() { this.getResourceType().regexpMatch("^Microsoft.App/containerApps@.*") }
1313

14+
/**
15+
* Returns the extendedLocation property.
16+
*/
17+
Expr getExtendedLocation() { result = this.getProperty("extendedLocation") }
18+
19+
/**
20+
* Returns the identity property.
21+
*/
22+
Expr getIdentity() { result = this.getProperty("identity") }
23+
24+
/**
25+
* Returns the kind property.
26+
*/
27+
StringLiteral getKind() { result = this.getProperty("kind") }
28+
29+
/**
30+
* Returns the managedBy property.
31+
*/
32+
StringLiteral getManagedBy() { result = this.getProperty("managedBy") }
33+
34+
/**
35+
* Returns the name property (overrides base Resource).
36+
*/
37+
override string getName() { result = super.getName() }
38+
1439
/**
1540
* Returns the properties object for the container app resource.
1641
*/
@@ -44,23 +69,44 @@ module Containers {
4469
result = this.getTemplate().getContainer(index)
4570
}
4671

47-
Network::Ingress getNetworkIngress() {
48-
result = this.getConfiguration().getNetworkIngress()
49-
}
72+
Network::Ingress getNetworkIngress() { result = this.getConfiguration().getNetworkIngress() }
5073

51-
Network::CorsPolicy getCorsPolicy() {
52-
result = this.getNetworkIngress().getCorsPolicy()
53-
}
74+
Network::CorsPolicy getCorsPolicy() { result = this.getNetworkIngress().getCorsPolicy() }
75+
76+
/**
77+
* Returns the SKU object for the container registry resource.
78+
*/
79+
Sku getSku() { result = this.getProperty("sku") }
80+
81+
Tags getTags() { result = this.getProperty("tags") }
5482

5583
/**
5684
* Returns a string representation of the container app resource.
5785
*/
5886
override string toString() { result = "ContainerResource" }
5987
}
6088

89+
class ContainerRegistry extends Resource {
90+
/**
91+
* Constructs a ContainerRegistry for Microsoft.ContainerRegistry/containerRegistries resources (2025-02-02-preview).
92+
*/
93+
ContainerRegistry() {
94+
this.getResourceType().regexpMatch("^Microsoft.ContainerRegistry/registries@.*$")
95+
}
96+
97+
/**
98+
* Returns the SKU object for the container registry resource.
99+
*/
100+
Sku getSku() { result = this.getProperty("sku") }
101+
102+
Tags getTags() { result = this.getProperty("tags") }
103+
104+
override string toString() { result = "ContainerRegistry" }
105+
}
106+
61107
module ContainerProperties {
62108
/**
63-
* Represents the properties object for a container app resource.
109+
* Represents the properties object for a container app resource (2025-02-02-preview).
64110
*/
65111
class Properties extends Object {
66112
private ContainerResource containerResource;
@@ -80,11 +126,31 @@ module Containers {
80126
*/
81127
ContainerConfiguration getConfiguration() { result = this.getProperty("configuration") }
82128

129+
/**
130+
* Returns the environmentId property.
131+
*/
132+
StringLiteral getEnvironmentId() { result = this.getProperty("environmentId") }
133+
134+
/**
135+
* Returns the managedEnvironmentId property.
136+
*/
137+
StringLiteral getManagedEnvironmentId() { result = this.getProperty("managedEnvironmentId") }
138+
139+
/**
140+
* Returns the patchingConfiguration property.
141+
*/
142+
Expr getPatchingConfiguration() { result = this.getProperty("patchingConfiguration") }
143+
83144
/**
84145
* Returns the template property.
85146
*/
86147
ContainerTemplate getTemplate() { result = this.getProperty("template") }
87148

149+
/**
150+
* Returns the workloadProfileName property.
151+
*/
152+
StringLiteral getWorkloadProfileName() { result = this.getProperty("workloadProfileName") }
153+
88154
string toString() { result = "ContainerProperties" }
89155
}
90156

@@ -109,6 +175,15 @@ module Containers {
109175
*/
110176
ContainerSecret getSecrets() { result = this.getProperty("secrets").(Array).getElements() }
111177

178+
ContainerSecret getSecret(string name) {
179+
exists(ContainerSecret secret |
180+
secret = this.getSecrets() and
181+
secret.getName().getValue() = name
182+
|
183+
result = secret
184+
)
185+
}
186+
112187
/**
113188
* Returns the active revisions mode as a StringLiteral.
114189
*/
@@ -124,6 +199,67 @@ module Containers {
124199
*/
125200
Expr getTemplate() { result = this.getProperty("template") }
126201

202+
/**
203+
* Returns the Dapr configuration object, if present.
204+
*
205+
* @return The Dapr configuration expression.
206+
*/
207+
Expr getDapr() { result = this.getProperty("dapr") }
208+
209+
/**
210+
* Returns the identity settings object, if present.
211+
*
212+
* @return The identity settings expression.
213+
*/
214+
Expr getIdentitySettings() { result = this.getProperty("identitySettings") }
215+
216+
/**
217+
* Returns the ingress configuration object, if present.
218+
*
219+
* @return The ingress configuration expression.
220+
*/
221+
Expr getIngress() { result = this.getProperty("ingress") }
222+
223+
/**
224+
* Returns all container registries defined in the configuration.
225+
*
226+
* @return The container registry objects as an array.
227+
*/
228+
ContainerRegistry getRegistries() {
229+
result = this.getProperty("registries").(Array).getElements()
230+
}
231+
232+
/**
233+
* Returns a specific container registry by index.
234+
*
235+
* @param index The index of the registry.
236+
* @return The container registry at the specified index.
237+
*/
238+
ContainerRegistry getRegistry(int index) {
239+
result = this.getProperty("registries").(Array).getElement(index)
240+
}
241+
242+
/**
243+
* Returns the runtime configuration object, if present.
244+
*
245+
* @return The runtime configuration expression.
246+
*/
247+
Expr getRuntime() { result = this.getProperty("runtime") }
248+
249+
/**
250+
* Returns the service configuration object, if present.
251+
*
252+
* @return The service configuration expression.
253+
*/
254+
Expr getService() { result = this.getProperty("service") }
255+
256+
/**
257+
* Returns the target label property, if present.
258+
*
259+
* @return The target label string literal.
260+
*/
261+
StringLiteral getTargetLabel() { result = this.getProperty("targetLabel") }
262+
127263
string toString() { result = "ContainerConfiguration" }
128264
}
129265

@@ -172,6 +308,38 @@ module Containers {
172308
*/
173309
ContainerApp getContainers() { result = this.getProperty("containers").(Array).getElements() }
174310

311+
/**
312+
* Returns the initContainers defined in the template.
313+
*/
314+
Expr getInitContainers() { result = this.getProperty("initContainers") }
315+
316+
/**
317+
* Returns the revisionSuffix property.
318+
*/
319+
StringLiteral getRevisionSuffix() { result = this.getProperty("revisionSuffix") }
320+
321+
/**
322+
* Returns the scale property.
323+
*/
324+
Expr getScale() { result = this.getProperty("scale") }
325+
326+
/**
327+
* Returns the serviceBinds property.
328+
*/
329+
Expr getServiceBinds() { result = this.getProperty("serviceBinds") }
330+
331+
/**
332+
* Returns the terminationGracePeriodSeconds property.
333+
*/
334+
Expr getTerminationGracePeriodSeconds() {
335+
result = this.getProperty("terminationGracePeriodSeconds")
336+
}
337+
338+
/**
339+
* Returns the volumes property.
340+
*/
341+
Expr getVolumes() { result = this.getProperty("volumes") }
342+
175343
/**
176344
* Returns a specific container by index from the template.
177345
*/
@@ -292,5 +460,37 @@ module Containers {
292460

293461
string toString() { result = "ContainerEnv" }
294462
}
463+
464+
class ContainerRegistry extends Object {
465+
private ContainerConfiguration configuration;
466+
467+
/**
468+
* Constructs a ContainerRegistry for the given configuration.
469+
*/
470+
ContainerRegistry() { this = configuration.getProperty("registries").(Array).getElements() }
471+
472+
/**
473+
* Returns the registry server URL.
474+
*/
475+
StringLiteral getServer() { result = this.getProperty("server") }
476+
477+
/**
478+
* Returns the username for the registry.
479+
*/
480+
StringLiteral getUsername() { result = this.getProperty("username") }
481+
482+
/**
483+
* Returns the password for the registry.
484+
*/
485+
StringLiteral getPassword() {
486+
exists(StringLiteral ref | ref = this.getProperty("passwordSecretRef") |
487+
result = configuration.getSecret(ref.getValue()).getValue()
488+
)
489+
or
490+
result = this.getProperty("password")
491+
}
492+
493+
string toString() { result = "ContainerRegistry" }
494+
}
295495
}
296496
}

ql/lib/codeql/bicep/frameworks/Microsoft/General.qll

Lines changed: 19 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11,18 +11,28 @@ class Sku extends Object {
1111
/**
1212
* Returns the SKU name (e.g., Basic, Standard, Premium).
1313
*/
14-
string getName() {
15-
result = this.getProperty("name").(StringLiteral).getValue()
16-
}
14+
string getName() { result = this.getProperty("name").(StringLiteral).getValue() }
1715

1816
/**
1917
* Returns the SKU tier (e.g., Basic, Standard, Premium).
2018
*/
21-
string getTier() {
22-
result = this.getProperty("tier").(StringLiteral).getValue()
23-
}
19+
string getTier() { result = this.getProperty("tier").(StringLiteral).getValue() }
2420

25-
string toString() {
26-
result = "SKU"
27-
}
21+
string toString() { result = "SKU" }
22+
}
23+
24+
class Tags extends Object {
25+
private Resource resource;
26+
27+
/**
28+
* Constructs a Tags object for the given resource.
29+
*/
30+
Tags() { this = resource.getProperty("tags") }
31+
32+
/**
33+
* Returns the value of a tag by its key.
34+
*/
35+
Literals getTag(string key) { result = this.getProperty(key) }
36+
37+
string toString() { result = "Tags" }
2838
}
Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1,11 @@
1-
| app.bicep:2:1:78:1 | ContainerResource |
1+
containers
2+
| app.bicep:14:1:101:1 | ContainerResource |
3+
containerConfig
4+
| app.bicep:14:1:101:1 | ContainerResource | app.bicep:19:20:63:5 | ContainerConfiguration |
5+
containerIngress
6+
| app.bicep:14:1:101:1 | ContainerResource | app.bicep:20:16:44:7 | NetworkIngress |
7+
containerSecrets
8+
| app.bicep:14:1:101:1 | ContainerResource | app.bicep:46:9:49:9 | ContainerSecret |
9+
| app.bicep:14:1:101:1 | ContainerResource | app.bicep:50:9:53:9 | ContainerSecret |
10+
containerReg
11+
| app.bicep:14:1:101:1 | ContainerResource | app.bicep:56:9:60:9 | ContainerRegistry |
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,26 @@
11
import bicep
22

33
query predicate containers(Containers::ContainerResource container) { any() }
4+
5+
query predicate containerConfig(
6+
Containers::ContainerResource container,
7+
Containers::ContainerProperties::ContainerConfiguration config
8+
) {
9+
container.getConfiguration() = config
10+
}
11+
12+
query predicate containerIngress(Containers::ContainerResource container, Network::Ingress ingress) {
13+
container.getNetworkIngress() = ingress
14+
}
15+
16+
query predicate containerSecrets(
17+
Containers::ContainerResource container, Containers::ContainerProperties::ContainerSecret secrets
18+
) {
19+
container.getConfiguration().getSecrets() = secrets
20+
}
21+
22+
query predicate containerReg(
23+
Containers::ContainerResource container, Containers::ContainerProperties::ContainerRegistry reg
24+
) {
25+
reg = container.getConfiguration().getRegistries()
26+
}

ql/test/library-tests/frameworks/containers/app.bicep

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,15 @@
1+
resource myRegistry 'Microsoft.ContainerRegistry/registries@2025-04-01' = {
2+
name: 'myregistry'
3+
location: 'eastus'
4+
sku: {
5+
name: 'Standard'
6+
}
7+
adminUserEnabled: true
8+
tags: {
9+
environment: 'dev'
10+
}
11+
}
12+
113
// Example Bicep file for a Container App with various settings
214
resource myContainerApp 'Microsoft.App/containerApps@2022-03-01' = {
315
name: 'my-container-app'
@@ -35,6 +47,17 @@ resource myContainerApp 'Microsoft.App/containerApps@2022-03-01' = {
3547
name: 'my-secret'
3648
value: 'supersecretvalue'
3749
}
50+
{
51+
name: 'acr-password'
52+
value: 'myacrpassword'
53+
}
54+
]
55+
registries: [
56+
{
57+
server: 'myregistry.azurecr.io'
58+
username: 'myacrusername'
59+
passwordSecretRef: 'acr-password'
60+
}
3861
]
3962
activeRevisionsMode: 'Multiple'
4063
}

0 commit comments

Comments
 (0)