diff --git a/lib/gitlab/ci/config/node/job.rb b/lib/gitlab/ci/config/node/job.rb
new file mode 100644
index 0000000000000000000000000000000000000000..5be8cb39a873f60a5c25c3a8d749ddc844e90415
--- /dev/null
+++ b/lib/gitlab/ci/config/node/job.rb
@@ -0,0 +1,14 @@
+module Gitlab
+  module Ci
+    class Config
+      module Node
+        ##
+        # Entry that represents a concrete CI/CD job.
+        #
+        class Job < Entry
+          include Configurable
+        end
+      end
+    end
+  end
+end
diff --git a/spec/lib/gitlab/ci/config/node/job_spec.rb b/spec/lib/gitlab/ci/config/node/job_spec.rb
new file mode 100644
index 0000000000000000000000000000000000000000..7dd25a23c83d09a3274c4f7091029242995af51a
--- /dev/null
+++ b/spec/lib/gitlab/ci/config/node/job_spec.rb
@@ -0,0 +1,36 @@
+require 'spec_helper'
+
+describe Gitlab::Ci::Config::Node::Job do
+  let(:entry) { described_class.new(config) }
+
+  describe 'validations' do
+    context 'when entry config value is correct' do
+      let(:config) { { script: 'rspec' } }
+
+      describe '#value' do
+        it 'returns key value' do
+          expect(entry.value).to eq(script: 'rspec')
+        end
+      end
+
+      describe '#valid?' do
+        it 'is valid' do
+          expect(entry).to be_valid
+        end
+      end
+    end
+
+    context 'when entry value is not correct' do
+      context 'incorrect config value type' do
+        let(:config) { ['incorrect'] }
+
+        describe '#errors' do
+          it 'saves errors' do
+            expect(entry.errors)
+              .to include 'job config should be a hash'
+          end
+        end
+      end
+    end
+  end
+end