> For the complete documentation index, see [llms.txt](https://docs.veedna.com/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://docs.veedna.com/sca360-flexible-deployment-for-data-center-cloud-integrated-environments/configuration.md).

# Configuration

You can use the following advanced configuration options to customize Lineaje SCA360 for your organization’s needs.

* [Configure Upload Automation](#configure-upload-automation)
* [Upload Metadata Files for Upload Automation](#upload-metadata-files-for-upload-automation)

## Configure Upload Automation

To allow the VM to access the metadata file, create an `upload_config.yaml` file. This file holds the configuration for images discovery and integrations.

1. Create a `/opt/veecli/upload_config.yaml` using the specifications in the following upload\_config.yaml file.

```
supported_orgs:
  - "<org_name_1>"
  - "<org_name_2>"
 
images:
  - aws-account-id: "<aws_account_id>"
    org-name: "<org_name>"
    discovery-logic: "<s3-path>"
    repository-url: "<account_id>.dkr.ecr.<region>.amazonaws.com/<repository-name>"
    s3-path: "s3://<bucket-name>/<path-prefix>/"
    role_arn: "arn:aws:iam::<account_id>:role/<role_name>"
    region: "<aws_region>"
 
amis:
  - aws-account-id: "<aws_account_id>"
    org-name: "<org_name>"
    discovery-logic: "s3-path"
    unique-resource-id: "ami-<id>, snap-<id>, i-<instance_id>, arn:aws:ec2:<region>:<account_id>:instance/<instance_id>"
    s3-path: "s3://<bucket-name>/<path-prefix>/"
    role_arn: "arn:aws:iam::<account_id>:role/<role_name>"
    region: "<aws_region>"
```

2. Run the upload\_automation script in the background.
   1. Open a tmux terminal using `tmux new-session -t upload_automation`
   2. Run command to start automation `cd /opt/veecli && python3 upload_automation.py`

      1. For **--wait**, the default value is 24 hours. The script iterates `upload_config.yaml` every 24 hours.
      2. For **--time**, the default value is `00:00`. The script begins waiting from the specified time.

         Example: If `--time 05:30` and `--wait 8` are set, the script performs initial discovery at `05:30`, then repeats every `8` hours, at `13:30` and `21:30`.

      <figure><img src="/files/PtUTHw2GopBwS0WNhmwr" alt="upload automation script"><figcaption></figcaption></figure>

## Upload Metadata Files for Upload Automation

Uploading metadata files enables Lineaje SCA360 to discover specific images, associate accurate product details with each image, and maintain privacy by only uploading SBOM metadata tar files to Lineaje infrastructure.

1. Create an image metadata file in YAML format. This file contains key-value pairs describing product information for an Image, AMI, or AWS Lambda function.
2. Store the metadata file in Amazon S3 using the following directory structure:\
   `s3://<bucket-name>/lineaje-data-science/<groupname>/<image-digest/unique-resource-id>.yaml`

   Example: `s3://<lineaje-metafiles-bucket>/lineaje-data-science/data-science/org_name/fb93015b83a2570123456789053ad9ccde3fca76df218b0b91b649f3eadbb8.ya`
3. Name the file using a unique identifier, preferably the SHA256 hash of the image (without the sha256: prefix). The filename is also used for ignore files if SBOM generation is performed for the resource.
4. Include the following mandatory fields in the metadata file:
   * **group:** Organizational hierarchy (e.g., root-org/demo-ush).
   * **project:** Project name to appear in the Lineaje tenant.
   * **version:** Version of the project.
   * **repository-url** (Required for ECR scans): Full ECR repository URI.
   * **image-hash** (Required for ECR scans): SHA256 hash of the image.
   * **unique-resource-id** (Required for AMI/Lambda scans)**:** Unique resource ID.
   * **region** (Required for AMI/Lambda scans): AWS region where the resource is located.
   * **image-creation-date:** Timestamp in ISO 8601 format (e.g., `2025-03-07T13:29:15.000Z`).
   * **sdlc-state:** Software Development Life Cycle state (e.g., `Dev`, `Stage`, `Prod`).
   * **entrypoint:** Optional; can be `null`.
5. Add the following recommended fields for better classification:
   * **description**: Brief description of the image or resource.
   * **tags**: Key-value tags for classification.
   * **owner**: Team or individual responsible for the resource.
6. For ECR images, name the metadata file using `<image_hash>.yaml`

An example file name is `214ae3a3da7c0f0caf17049fdcdeab60585dae60c07d3891f99718a3bb1d8043.yaml`.&#x20;

The following is an example of an ECR metadata content:

```
metadata:
  group: "customer_org"
  project: "project_name_here"
  version: "version_here"
  repository-url: "ecr_repo_url_here"
  image-creation-date: "2025-03-07T13:29:15.000Z"
  image-hash: "image_hash_here"
  sdlc-state: "Prod"
  entrypoint: null
```

7. For source code, name the metadata using `<last_commit_hash>.yaml`***.*** An example file name is `77a9afb0f01bf885231a1a8f5fb25dd0196c0a24.yaml`.&#x20;

The following is an example of a source code metadata content:

```
metadata:
  group: "customer_org"
  project: "project_name_here"
  version: "1.0"
  repository-url: "github_repo_url_here"
  matching-ref: "v1"
  type: "npm"
  sdlc-state: "Prod"
```

## Trigger a Scan Using GitHub Action Workflow

This workflow generates and uploads an image metadata YAML file to S3, triggered manually via `workflow_dispatch` with inputs for the ECR image details, SDLC state, and an optional fix-PR flag. When `create_fix_pr` is enabled, the metadata includes source repository details (repo, branch, Dockerfile path) pulled from repo secrets, enabling Lineaje's automated fix flow post-scan. Configuration values like `AWS_REGION`, `AWS_BUCKET`, and `REPOSITORY_URI` are defined as workflow-level environment variables, but can be moved to repository secrets or organization variables depending on your team's preference. The workflow requires `AWS_ACCESS_KEY_ID` and `AWS_SECRET_ACCESS_KEY` secrets for S3 upload access.

{% code overflow="wrap" %}

```yml
name: Generate and Upload Metadata

on:
  workflow_dispatch:
    inputs:
      image_repo:
        description: "Repository name inside the registry"
        required: true
      image_name:
        description: "Name of the image"
        required: true
      image_tag:
        description: "Tag of the image"
        required: true
      image_hash:
        description: "Image hash (with or without 'sha256:')"
        required: true
      group:
        description: "Lineaje organization group"
        required: false
        default: "Root Organization"
      sdlc_state:
        description: "SDLC state (e.g. Dev, Test, Prod)"
        required: false
        default: "Test"
      create_fix_pr:
        description: "Whether to create a fix PR"
        required: false
        default: "false"

jobs:
  generate-and-upload:
    runs-on: ubuntu-latest

    env:
      AWS_REGION: "us-east-1"
      AWS_BUCKET: "xxx"
      REPOSITORY_URI: "xxx"

    steps:
      - name: Checkout repository
        uses: actions/checkout@v4

      - name: Set up AWS credentials
        uses: aws-actions/configure-aws-credentials@v4
        with:
          aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY_ID }}
          aws-secret-access-key: ${{ secrets.AWS_SECRET_ACCESS_KEY }}
          aws-region: ${{ env.AWS_REGION }}

      - name: Create metadata file
        run: |
          IMAGE_REPO="${{ github.event.inputs.image_repo }}"
          IMAGE_NAME="${{ github.event.inputs.image_name }}"
          IMAGE_TAG="${{ github.event.inputs.image_tag }}"
          IMAGE_HASH="${{ github.event.inputs.image_hash }}"
          GROUP="${{ github.event.inputs.group }}"
          SDLC_STATE="${{ github.event.inputs.sdlc_state }}"
          CREATE_FIX_PR="${{ github.event.inputs.create_fix_pr }}"
          SOURCE_REPO="${{ secrets.SOURCE_REPO }}"
          SOURCE_BRANCH="${{ secrets.SOURCE_BRANCH }}"
          SOURCE_DOCKERFILE="${{ secrets.SOURCE_DOCKERFILE }}"

          CLEAN_HASH=$(echo "$IMAGE_HASH" | sed 's/^sha256://')
          if [[ "$IMAGE_HASH" != sha256:* ]]; then
            FULL_HASH="sha256:${CLEAN_HASH}"
          else
            FULL_HASH="$IMAGE_HASH"
          fi

          FILE_NAME="${CLEAN_HASH}_metadata.yaml"

          if [[ "$CREATE_FIX_PR" == "true" ]]; then
            {
              echo "metadata:"
              echo "  project: \"$IMAGE_NAME\""
              echo "  version: \"$IMAGE_TAG\""
              echo "  repository-url: \"${REPOSITORY_URI}/${IMAGE_REPO}/${IMAGE_NAME}\""
              echo "  region: \"${AWS_REGION}\""
              echo "  image-hash: \"$FULL_HASH\""
              echo "  group: \"$GROUP\""
              echo "  sdlc-state: \"$SDLC_STATE\""
              echo "  create-fix-pr: true"
              echo "  source:"
              echo "    repo: \"$SOURCE_REPO\""
              echo "    branch: \"$SOURCE_BRANCH\""
              echo "    dockerfile: \"$SOURCE_DOCKERFILE\""
            } > "$FILE_NAME"
          else
            {
              echo "metadata:"
              echo "  project: \"$IMAGE_NAME\""
              echo "  version: \"$IMAGE_TAG\""
              echo "  repository-url: \"${REPOSITORY_URI}/${IMAGE_REPO}/${IMAGE_NAME}\""
              echo "  region: \"${AWS_REGION}\""
              echo "  image-hash: \"$FULL_HASH\""
              echo "  group: \"$GROUP\""
              echo "  sdlc-state: \"$SDLC_STATE\""
              echo "  create-fix-pr: false"
            } > "$FILE_NAME"
          fi

          echo "Generated metadata file: ${FILE_NAME}"

      - name: Upload to S3
        run: |
          IMAGE_HASH="${{ github.event.inputs.image_hash }}"
          CLEAN_HASH=$(echo "$IMAGE_HASH" | sed 's/^sha256://')
          FILE_NAME="${CLEAN_HASH}_metadata.yaml"
          S3_PATH="s3://${AWS_BUCKET}/metadata/${FILE_NAME}"

          echo "Uploading ${FILE_NAME} to ${S3_PATH}"
          aws s3 cp "$FILE_NAME" "$S3_PATH" --region "$AWS_REGION"

          echo "Uploaded to: ${S3_PATH}"
```

{% endcode %}


---

# Agent Instructions
This documentation is published with GitBook. GitBook is the documentation platform designed so that both humans and AI agents can read, navigate, and reason over technical content effectively. Learn more at gitbook.com.

## Querying This Documentation
If you need additional information that is not directly available in this page, you can query the documentation dynamically by asking a question.

Perform an HTTP GET request on the current page URL with the `ask` query parameter, and the optional `goal` query parameter:

```
GET https://docs.veedna.com/sca360-flexible-deployment-for-data-center-cloud-integrated-environments/configuration.md?ask=<question>&goal=<endgoal>
```

`ask` is the immediate question: it should be specific, self-contained, and written in natural language.
`goal` is optional and describes the broader end goal you are ultimately trying to accomplish on behalf of the user. GitBook uses it to tailor the answer towards what is most useful for that goal.

The response will contain a direct answer to the question and relevant excerpts and sources from the documentation.

Use this mechanism when the answer is not explicitly present in the current page, you need clarification or additional context, or you want to retrieve related documentation sections.
