Skip to content

Commit 4a78d5d

Browse files
prodion23nebhale
authored andcommitted
Contrast Security Framework
This change adds the Contrast Security Framework which detects a service with name/label/tag of contrast-security. [cloudfoundry#446]
1 parent 9fdd1df commit 4a78d5d

7 files changed

Lines changed: 245 additions & 0 deletions

File tree

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,7 @@ To learn how to configure various properties of the buildpack, follow the "Confi
7474
* Standard Frameworks
7575
* [AppDynamics Agent](docs/framework-app_dynamics_agent.md) ([Configuration](docs/framework-app_dynamics_agent.md#configuration))
7676
* [Container Customizer](docs/framework-container_customizer.md) ([Configuration](docs/framework-container_customizer.md#configuration))
77+
* [Contrast Security Agent](docs/framework-contrast_security_agent.md) ([Configuration](docs/framework-contrast_security_agent.md#configuration))
7778
* [Debug](docs/framework-debug.md) ([Configuration](docs/framework-debug.md#configuration))
7879
* [Dyadic EKM Security Provider](docs/framework-dyadic_ekm_security_provider.md) ([Configuration](docs/framework-dyadic_ekm_security_provider.md#configuration))
7980
* [Dynatrace Appmon Agent](docs/framework-dynatrace_appmon_agent.md) ([Configuration](docs/framework-dynatrace_appmon_agent.md#configuration))

config/components.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@ frameworks:
4040
- "JavaBuildpack::Framework::AppDynamicsAgent"
4141
- "JavaBuildpack::Framework::ContainerCustomizer"
4242
- "JavaBuildpack::Framework::ContainerSecurityProvider"
43+
- "JavaBuildpack::Framework::ContrastSecurityAgent"
4344
- "JavaBuildpack::Framework::Debug"
4445
- "JavaBuildpack::Framework::DyadicEkmSecurityProvider"
4546
- "JavaBuildpack::Framework::DynatraceAppmonAgent"

config/contrast_security_agent.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Cloud Foundry Java Buildpack
2+
# Copyright 2013-2017 the original author or authors.
3+
#
4+
# Licensed under the Apache License, Version 2.0 (the "License");
5+
# you may not use this file except in compliance with the License.
6+
# You may obtain a copy of the License at
7+
#
8+
# http://www.apache.org/licenses/LICENSE-2.0
9+
#
10+
# Unless required by applicable law or agreed to in writing, software
11+
# distributed under the License is distributed on an "AS IS" BASIS,
12+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13+
# See the License for the specific language governing permissions and
14+
# limitations under the License.
15+
16+
# Configuration for the ContrastSecurity framework
17+
---
18+
version: 3.+
19+
repository_root: "https://artifacts.contrastsecurity.com/agents/java/"
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
# Contrast Security Agent Framework
2+
The Contrast Security Agent Framework causes an application to be automatically configured to work with a bound [Contrast Security Service][].
3+
4+
<table>
5+
<tr>
6+
<td><strong>Detection Criterion</strong></td><td>Existence of a single bound Contrast Security service. The existence of an Contrast Security service defined by the <a href="http://docs.cloudfoundry.org/devguide/deploy-apps/environment-variable.html#VCAP-SERVICES"><code>VCAP_SERVICES</code></a> payload containing a service name, label or tag with <code>contrast-security</code> as a substring.
7+
</td>
8+
</tr>
9+
</table>
10+
Tags are printed to standard output by the buildpack detect script
11+
12+
## User-Provided Service
13+
When binding ContrastSecurity using a user-provided service, it must have name or tag with `contrast-security` in it. The credential payload can contain the following entries:
14+
15+
| Name | Description
16+
| ---- | -----------
17+
| `teamserver_url` | The base URL in which your user has access to and the URL to which the Agent will report. ex: https://app.contrastsecurity.com
18+
| `username` | The account name to use when downloading the agent
19+
| `org_uuid` | The org uuid to send app information to, this is the org that your bound application will appear within
20+
| `api_key` | Your user's api key
21+
| `service_key` | Your user's service key
22+
23+
24+
## Configuration
25+
For general information on configuring the buildpack, including how to specify configuration values through environment variables, refer to [Configuration and Extension][].
26+
27+
The framework can be configured by modifying the [`config/contrast_security_agent.yml`][] file in the buildpack fork. The framework uses the [`Repository` utility support][repositories] and so it supports the [version syntax][] defined there.
28+
29+
| Name | Description
30+
| ---- | -----------
31+
| `repository_root` | The URL of the Contrast Security repository index ([details][repositories]).
32+
| `version` | The version of Contrast Security to use. Candidate versions can be found in [this listing][].
33+
34+
[Contrast Security]: https://www.contrastsecurity.com
35+
[Configuration and Extension]: ../README.md#configuration-and-extension
36+
[Contrast Security Service]: https://www.contrastsecurity.com
37+
[`config/contrast_security_agent.yml`]: ../config/contrast_security_agent.yml
38+
[Configuration and Extension]: ../README.md#configuration-and-extension
39+
[repositories]: extending-repositories.md
40+
[this listing]: https://artifacts.contrastsecurity.com/agents/java/index.yml
41+
[version syntax]: extending-repositories.md#version-syntax-and-ordering
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
# Encoding: utf-8
2+
3+
# Cloud Foundry Java Buildpack
4+
# Copyright 2013-2017 the original author or authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
require 'fileutils'
19+
require 'java_buildpack/component/versioned_dependency_component'
20+
require 'java_buildpack/framework'
21+
require 'rexml/document'
22+
23+
module JavaBuildpack
24+
module Framework
25+
26+
# Encapsulates the functionality for running the Contrast Security Agent support.
27+
class ContrastSecurityAgent < JavaBuildpack::Component::VersionedDependencyComponent
28+
29+
# (see JavaBuildpack::Component::BaseComponent#compile)
30+
def compile
31+
download_jar(boot_class_name)
32+
build_contrast_configuration
33+
@droplet.copy_resources
34+
end
35+
36+
# (see JavaBuildpack::Component::BaseComponent#release)
37+
def release
38+
app_name = @application.details['application_name'] || 'ROOT'
39+
java_opts = @droplet.java_opts
40+
java_opts.add_system_property('contrast.dir', '$TMPDIR')
41+
java_opts.add_system_property('contrast.override.appname', app_name)
42+
path = java_opts.qualify_path(@droplet.sandbox)
43+
java_opts.add_preformatted_options("-javaagent:#{path}/#{boot_class_name}=#{path}/contrast.config")
44+
end
45+
46+
protected
47+
48+
# (see JavaBuildpack::Component::VersionedDependencyComponent#supports?)
49+
def supports?
50+
@application.services.one_service?(CONTRAST_FILTER, TEAMSERVER_URL, USERNAME, API_KEY, SERVICE_KEY)
51+
end
52+
53+
private
54+
55+
API_KEY = 'api_key'.freeze
56+
CONTRAST_FILTER = 'contrast-security'.freeze
57+
SERVICE_KEY = 'service_key'.freeze
58+
TEAMSERVER_URL = 'teamserver_url'.freeze
59+
USERNAME = 'username'.freeze
60+
61+
private_constant :API_KEY
62+
private_constant :CONTRAST_FILTER
63+
private_constant :SERVICE_KEY
64+
private_constant :TEAMSERVER_URL
65+
private_constant :USERNAME
66+
67+
PLUGIN_PACKAGE = 'com.aspectsecurity.contrast.runtime.agent.plugins.'.freeze
68+
69+
def credentials
70+
@application.services.find_service(CONTRAST_FILTER)['credentials']
71+
end
72+
73+
def boot_class_name
74+
version = @version.to_s.split('_')[0]
75+
"contrast-engine-#{version}.jar"
76+
end
77+
78+
def build_contrast_configuration
79+
doc = REXML::Document.new
80+
contrast = doc.add_element('contrast')
81+
(contrast.add_element 'id').add_text('default')
82+
(contrast.add_element 'global-key').add_text(credentials[API_KEY])
83+
user = contrast.add_element('user')
84+
(user.add_element 'id').add_text(credentials[USERNAME])
85+
(user.add_element 'key').add_text(credentials[SERVICE_KEY])
86+
(contrast.add_element 'url').add_text("#{credentials[TEAMSERVER_URL]}/Contrast/s/")
87+
(contrast.add_element 'results-mode').add_text('never')
88+
89+
add_plugins(contrast)
90+
91+
contrast_config.open(File::CREAT | File::WRONLY) { |f| f.write(doc) }
92+
end
93+
94+
def add_plugins(config)
95+
plugin_package = 'com.aspectsecurity.contrast.runtime.agent.plugins.'
96+
plugin_group = config.add_element('plugins')
97+
(plugin_group.add_element 'plugin').add_text("#{plugin_package}.security.SecurityPlugin")
98+
(plugin_group.add_element 'plugin').add_text("#{plugin_package}.architecture.ArchitecturePlugin")
99+
(plugin_group.add_element 'plugin').add_text("#{plugin_package}.appupdater.ApplicationUpdatePlugin")
100+
(plugin_group.add_element 'plugin').add_text("#{plugin_package}.sitemap.SitemapPlugin")
101+
(plugin_group.add_element 'plugin').add_text("#{plugin_package}.frameworks.FrameworkSupportPlugin")
102+
(plugin_group.add_element 'plugin').add_text("#{plugin_package}.http.HttpPlugin")
103+
end
104+
105+
def contrast_config
106+
@droplet.sandbox + 'contrast.config'
107+
end
108+
109+
end
110+
111+
end
112+
end

spec/fixtures/stub-contrast-security-agent.jar

Whitespace-only changes.
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
# Encoding: utf-8
2+
3+
# Cloud Foundry Java Buildpack
4+
# Copyright 2013-2016 the original author or authors.
5+
#
6+
# Licensed under the Apache License, Version 2.0 (the "License");
7+
# you may not use this file except in compliance with the License.
8+
# You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing, software
13+
# distributed under the License is distributed on an "AS IS" BASIS,
14+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
# See the License for the specific language governing permissions and
16+
# limitations under the License.
17+
18+
require 'spec_helper'
19+
require 'component_helper'
20+
require 'java_buildpack/framework/contrast_security_agent'
21+
require 'java_buildpack/util/tokenized_version'
22+
23+
describe JavaBuildpack::Framework::ContrastSecurityAgent do
24+
include_context 'component_helper'
25+
let(:configuration) do
26+
{ 'teamserver_url' => 'a_url',
27+
'org_uuid' => '12345',
28+
'username' => 'contrast_user',
29+
'api_key' => 'api_test',
30+
'service_key' => 'service_test' }
31+
end
32+
33+
it 'does not detect without contrastsecurity service' do
34+
expect(component.detect).to be_nil
35+
end
36+
37+
context do
38+
before do
39+
allow(services).to receive(:one_service?).with(/contrast[-]?security/,
40+
'teamserver_url','username', 'api_key', 'service_key').and_return(true)
41+
allow(services).to receive(:find_service).and_return('credentials' => :configuration)
42+
end
43+
44+
it 'detects with contrastsecurity service' do
45+
expect(component.detect).to eq("contrast-security-agent=#{version}")
46+
end
47+
48+
it 'downloads Contrast Security agent JAR',
49+
cache_fixture: 'stub-contrast-security-agent.jar' do
50+
51+
component.compile
52+
expect(sandbox + 'contrast-engine-0.0.0.jar').to exist
53+
end
54+
55+
it 'updates JAVA_OPTS' do
56+
component.release
57+
58+
expect(java_opts).to include('-javaagent:$PWD/.java-buildpack/contrast_security_agent/contrast-engine-0.0.0.jar'\
59+
'=$PWD/.java-buildpack/contrast_security_agent/contrast.config')
60+
expect(java_opts).to include('-Dcontrast.dir=$TMPDIR')
61+
expect(java_opts).to include('-Dcontrast.override.appname=test-application-name')
62+
end
63+
64+
it 'created contrast.config',
65+
cache_fixture: 'stub-contrast-security-agent.jar' do
66+
component.compile
67+
expect(sandbox + 'contrast.config').to exist
68+
end
69+
end
70+
71+
end

0 commit comments

Comments
 (0)