Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/actions/build-apm-jar/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,14 +13,14 @@ runs:
cd ..

- name: Capture custom jar
uses: actions/upload-artifact@v4
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # pin@v7
with:
name: newrelic-artifact
path: |
newrelic-java-agent/newrelic-java/build/zips/newrelic.zip

- name: configure aws credentials
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # pin@v6
with:
role-to-assume: arn:aws:iam::280901927509:role/github-actions/repo
aws-region: us-east-2
Expand Down
4 changes: 2 additions & 2 deletions .github/actions/setup-environment-inst-verifier/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ runs:

steps:
- name: Set up Javas
uses: actions/setup-java@v3
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # pin@v5
with:
distribution: 'temurin'
java-version: |
Expand Down Expand Up @@ -45,7 +45,7 @@ runs:

- name: Configure AWS Credentials
if: ${{ inputs.apm-aws-secret-access-key != '' }}
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # pin@v6
with:
aws-access-key-id: ${{ inputs.apm-aws-access-key-id }}
aws-secret-access-key: ${{ inputs.apm-aws-secret-access-key }}
Expand Down
10 changes: 5 additions & 5 deletions .github/actions/setup-environment/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ runs:

steps:
- name: Set up Javas
uses: actions/setup-java@v4
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # pin@v5
with:
distribution: 'temurin'
java-version: |
Expand All @@ -54,21 +54,21 @@ runs:
cat gradle.properties.gha >> gradle.properties

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v3
uses: gradle/actions/setup-gradle@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # pin@v6

- name: Setup Gradle options
shell: bash
run: echo "GRADLE_OPTIONS=--console=plain --parallel -Porg.gradle.java.installations.auto-detect=false -Porg.gradle.java.installations.fromEnv=JAVA_HOME_8_X64,JAVA_HOME_11_X64,JAVA_HOME_17_X64,JAVA_HOME_21_X64,JAVA_HOME_23_X64 -Prelease=${{ inputs.is-release }} -Prelease-suffix=${{ inputs.version-suffix }} " >> $GITHUB_ENV

# Restore the maven cache
- name: Cache local Maven repository
uses: actions/cache@v3
uses: actions/cache@v5
with:
path: ~/.m2/repository
key: ${{ runner.os }}-maven-${{ github.run_id }}

- name: Checkout APM agent
uses: actions/checkout@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
repository: ${{ inputs.apm-repo }}
ref: ${{ inputs.apm-branch }}
Expand Down Expand Up @@ -97,7 +97,7 @@ runs:

- name: Configure AWS Credentials
if: ${{ inputs.apm-aws-secret-access-key != '' }}
uses: aws-actions/configure-aws-credentials@v2
uses: aws-actions/configure-aws-credentials@d979d5b3a71173a29b74b5b88418bfda9437d885 # pin@v6
with:
aws-access-key-id: ${{ inputs.apm-aws-access-key-id }}
aws-secret-access-key: ${{ inputs.apm-aws-secret-access-key }}
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/X-Reusable-Build-Security-Agent.yml
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ jobs:

steps:
- name: Checkout CSEC Repo
uses: actions/checkout@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
ref: ${{ github.ref }}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/X-Reusable-VerifyInstrumentation.yml
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ jobs:
outputs:
modules: ${{ steps.set-modules.outputs.modules }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
ref: ${{ inputs.ref }}

Expand Down Expand Up @@ -58,7 +58,7 @@ jobs:
# GHA's IDE think the line below is broken. It is not.
matrix: ${{ fromJson(needs.read-modules.outputs.modules) }}
steps:
- uses: actions/checkout@v3
- uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
ref: ${{ inputs.ref }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/build-integrated-jar.yml
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ jobs:
run: echo "${{ toJSON(github.event.inputs) }}"

- name: Checkout CSEC Java agent
uses: actions/checkout@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
ref: ${{ github.ref }}

Expand Down
4 changes: 2 additions & 2 deletions .github/workflows/dependency-submission.yml
Original file line number Diff line number Diff line change
Expand Up @@ -14,9 +14,9 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout sources
uses: actions/checkout@v4
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
- name: Setup Java
uses: actions/setup-java@v4
uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # pin@v5
with:
distribution: 'temurin'
java-version: 8
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/publish-to-maven.yml
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ jobs:
runs-on: ubuntu-24.04
steps:
- name: Checkout APM agent
uses: actions/checkout@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
ref: ${{ github.ref }}

Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/repolinter.yml
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ jobs:
return data.data && data.data.default_branch === context.ref.split('/').slice(-1)[0]
- name: Checkout Self
if: ${{ steps.default-branch.outputs.result == 'true' }}
uses: actions/checkout@v2
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
- name: Run Repolinter
if: ${{ steps.default-branch.outputs.result == 'true' }}
uses: newrelic/repolinter-action@v1
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/verify-instrumentation-single.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ jobs:
run: echo "${{ toJSON(github.event.inputs) }}"

- name: Checkout CSEC Java agent
uses: actions/checkout@v3
uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # pin@v6
with:
ref: ${{ github.ref }}

Expand Down
87 changes: 87 additions & 0 deletions docs/LOCAL_DEVELOPMENT.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,87 @@
# Building and Running csec-java-agent Locally

This doc walks through building csec-java-agent agent end to end on a dev machine: the
base APM Java agent and the security agent.
## 1. Overview

`csec-java-agent` is built and published as a dependency for use in `newrelic-java-agent` only - it is not a standalone artifact you run by itself.

It depends on artifacts published by a fork of the APM Java agent:

- Repo: `k2io/newrelic-java-agent` (a New Relic fork, org `k2io`)
- Branch to use: `csec-dev`
- Referred to informally below as **"K2-JavaAgent"**

## 2. Prerequisites

- Install java AdoptOpenJDK 8 and java versions 11 and 17 as well.
- **JDK 8 is required** to build both repos. Configure it in
`~/.gradle/gradle.properties` file:
```properties
jdk8=/Library/Java/JavaVirtualMachines/adoptopenjdk-8.jdk/Contents/Home
```
- Two repos checked out locally:
1. `newrelic-java-agent` - https://github.com/k2io/newrelic-java-agent,
checked out on branch `csec-dev`.
2. `csec-java-agent` - https://github.com/newrelic/csec-java-agent.
- `./gradlew` works from each repo's own root.

## 3 - Build the Dependencies from APM Java Agent

All commands in this section run from the **`newrelic-java-agent` root**
(k2io fork, `csec-dev` branch).

### Step 1 - Publish prerequisite modules to Maven local

```bash
./gradlew clean \
:newrelic-api:publishToMavenLocal \
:agent-bridge:publishToMavenLocal \
:agent-bridge-datastore:publishToMavenLocal \
:newrelic-weaver-api:publishToMavenLocal \
:newrelic-weaver:publishToMavenLocal \
:newrelic-weaver-scala:publishToMavenLocal \
:newrelic-weaver-scala-api:publishToMavenLocal \
--parallel
```

## 4 - Build the CSEC Java Agent

All commands in this section run from the **`csec-java-agent` root**.
Publish API and agent locally.

### 4.1 - Build and publish the security API

```bash
./gradlew ${GRADLE_OPTIONS} :newrelic-security-api:publishToMavenLocal \
--parallel
```

### 4.2 - Build and publish the security agent

```bash
./gradlew ${GRADLE_OPTIONS} publishToMavenLocal \
--parallel
```

### Build the standalone security agent jar [OPTIONAL]

```bash
./gradlew clean jar --parallel
```

Artifacts land at:

```
newrelic-security-agent/build/libs
```

Only needed if you want the jar itself rather than just installing to Maven
local for `newrelic-java-agent` to pick up.
## References

- `csec-java-agent/README.md` - "Building" section (source for Part 2 baseline commands)
- `csec-java-agent/.github/actions/publish-csec-local/action.yml`
- `newrelic-java-agent/README.md` - "Building" section (source for Part 1 baseline commands)
- `newrelic-java-agent/.github/actions/setup-environment/action.yml` - `GRADLE_OPTIONS` definition
- [RELEASE.md](RELEASE.md) - build/package/publish steps and release CI workflows
73 changes: 73 additions & 0 deletions docs/RELEASE.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
# Releasing csec-java-agent

Step-by-step guide for release of csec-java-agent, plus what the GitHub Actions
workflows do at each stage. csec-java-agent is published as a dependency consumed by
`newrelic-java-agent` - releasing it does not produce a
standalone runnable artifact.

## 1. Pre-release

1. Confirm you're releasing off `main` - every publish workflow below builds from the pushed/
tagged ref, so a stray branch produces a stray artifact.
2. Bump CSEC version
- `agentVersion` in `gradle.properties` (root of this repo).
- Also update `securityAgentVersion` in `newrelic-java-agent/gradle.properties` (in k2-JavaAgent).
3. Update `Changelog.md` (Keep a Changelog format - see existing entries for style).
4. Open/merge the version-bump + changelog PR to `main` like any other change. This PR triggers
the same CI gates as any PR (section 2) plus, once merged, a snapshot publish (section 3).

## 2. CI gates (run automatically on every PR and push to `main`)

| Check | Workflow | What it does |
|---|---|---|
| Unit tests | `X-Reusable-Build-Security-Agent.yml` -> `.github/actions/unit-test` | Run unit tests and retries up to 4 times on failure before the job is marked failed. |
| CVE / dependency check | `dependency-submission.yml` | On every PR to `main`: submits the Gradle dependency graph (`newrelic-security-agent`/`newrelic-security-api` projects), then runs `actions/dependency-review-action` with `fail-on-severity: low` - **any newly-introduced CVE at low severity or above fails the PR check.** |
| Instrumentation verification | `verify-instrumentation.yml` -> `X-Reusable-VerifyInstrumentation.yml` | Not PR-gated - runs nightly (`cron: '0 0 * * *'`) against `main`, or on demand (`workflow_dispatch`/`workflow_call`). Reads every module under `instrumentation-security/` from `settings.gradle`, splits them across a paged matrix (GHA's 255-job matrix limit), and runs `:instrumentation:<module>:verifyInstrumentation` on **Java 17** for each. A Slack alert (`SLACK_WEBHOOK_URL_INST_VERIFIER`) fires on failure. |
## 3. Snapshot publish (automatic, no action needed)

Every push to `main` runs `publish-main-snapshot-to-maven.yml`, which calls the reusable
`publish-to-maven.yml` with `is-release=false`, `csec-run-unittest=true`,
`csec-run-instrumentation-verify=true`. Unit tests and instrumentation verification must pass
before it publishes `newrelic-security-api` and the CSEC agent to the Maven **snapshot**
repository via `./gradlew publish`.

Use this to sanity-check that a change resolves correctly as a dependency before cutting an
actual release.

## 4. Cut the release

1. Create a GitHub release (tag + release notes) from `main` in the csec-java-agent repo.
2. Publishing the release (`release: published`) triggers `publish-release-to-maven.yml`, which
calls `publish-to-maven.yml` with `is-release=true`, `csec-run-unittest=false`,
`csec-run-instrumentation-verify=false` (these already passed pre-merge/on `main`, so the
release run skips re-running them).
## 5. Post-release verification

- [ ] Confirm the Central Sonatype upload step in `publish-release-to-maven.yml` returned 200 -
visit https://central.sonatype.com/publishing/deployments to see the artifacts land.
- [ ] A silent Sonatype/GPG auth failure is the most likely release-day surprise - if the publish
step succeeded but the upload step failed, the artifacts are staged but not released; you
can re-run just the upload once credentials are fixed.
- [ ] Verify the Slack notification's `security-version`/`apm-version` match what you intended to
release.
- [ ] From K2io repo `newrelic-java-agent` bump the CSEC Version, raise a PR on newrelic's repo `newrelic-java-agent`
## Required secrets

| Secret | Used for |
|---|---|
| `SONATYPE_USERNAME` / `SONATYPE_PASSWORD` | Maven Central / Sonatype auth (publish + staging upload) |
| `SIGNING_KEY` / `SIGNING_KEY_ID` / `SIGNING_KEY_PASSWORD` | GPG-signing published artifacts |
| `APM_AWS_ACCESS_KEY_ID` / `APM_AWS_SECRET_ACCESS_KEY` | Pulling the proprietary instrumentation jar zip from S3 during setup |

## References

- `.github/workflows/dependency-submission.yml`
- `.github/workflows/verify-instrumentation.yml`, `X-Reusable-VerifyInstrumentation.yml`, `verify-instrumentation-single.yml`
- `.github/workflows/publish-main-snapshot-to-maven.yml`
- `.github/workflows/publish-release-to-maven.yml`
- `.github/workflows/publish-to-maven.yml`
- `.github/workflows/build-integrated-jar.yml`
- `.github/workflows/X-Reusable-Build-Security-Agent.yml`
- `.github/actions/unit-test/action.yml`, `setup-environment/action.yml`, `publish-csec-local/action.yml`
- `Changelog.md`, `gradle.properties`
- [LOCAL_DEVELOPMENT.md](LOCAL_DEVELOPMENT.md) - building and running the agent locally
Loading